Esempio n. 1
0
void MergeBounds(Ogre::SceneNode* node, Ogre::SceneNode* rootNode,
                  const Ogre::Matrix4& parentTransform, Ogre::AxisAlignedBox& aabb)
{
    // Get this nodes current transform
    Ogre::Matrix4 currentTransform = parentTransform;
    if (node != rootNode)
    {
        Ogre::Matrix4 localTransform(node->getOrientation());
        localTransform.setTrans(node->getPosition());
        currentTransform = currentTransform * localTransform;
    }

    // Merge this nodes objects
    Ogre::SceneNode::ObjectIterator object = node->getAttachedObjectIterator();
    while (object.hasMoreElements())
    {
        Ogre::AxisAlignedBox localAABB = object.getNext()->getBoundingBox();
        localAABB.transform(currentTransform);
        aabb.merge(localAABB);
    }

    // Iterate through all children and call this function on them
    Ogre::SceneNode::ChildNodeIterator child = node->getChildIterator();
    while (child.hasMoreElements())
    {
        MergeBounds(static_cast<Ogre::SceneNode*>(child.getNext()), rootNode, currentTransform, aabb);
    }
}
Esempio n. 2
0
void SelectionHandler::updateTrackedBoxes()
{
  M_HandleToBox::iterator it = boxes_.begin();
  M_HandleToBox::iterator end = boxes_.end();
  for (; it != end; ++it)
  {
    V_AABB aabbs;
    Picked p(it->first.first);
    p.extra_handles.insert(it->first.second);
    getAABBs(Picked(it->first.first), aabbs);

    if (!aabbs.empty())
    {
      Ogre::AxisAlignedBox combined;
      V_AABB::iterator aabb_it = aabbs.begin();
      V_AABB::iterator aabb_end = aabbs.end();
      for (; aabb_it != aabb_end; ++aabb_it)
      {
        combined.merge(*aabb_it);
      }

      createBox(std::make_pair(p.handle, it->first.second), combined, "RVIZ/Cyan");
    }
  }
}
Ogre::AxisAlignedBox GPUBillboardSet::calculateBillboardsBoundingBox(const std::vector<PhotoSynth::Vertex>& vertices)
{
	Ogre::AxisAlignedBox box;
	for (std::size_t i=0; i<vertices.size(); ++i)
		box.merge(vertices[i].position);	
	return box;
}
Esempio n. 4
0
	void RenderBoxScene::updateViewport()
	{
		// пр?нуле вылетает
		if ((mCanvas->getWidth() <= 1) || (mCanvas->getHeight() <= 1))
			return;

		if ((nullptr != mEntity) && (nullptr != mCamera))
		{
			// не ¤сн? нужн?ли раст¤гивать камеру, установленну?юзером
			mCamera->setAspectRatio((float)mCanvas->getWidth() / (float)mCanvas->getHeight());

			// вычисл¤ем рассто¤ни? чтоб?бы?виде?весь объект
			Ogre::AxisAlignedBox box;

			box.merge(mEntity->getBoundingBox().getMinimum() + mEntity->getParentSceneNode()->_getDerivedPosition());
			box.merge(mEntity->getBoundingBox().getMaximum() + mEntity->getParentSceneNode()->_getDerivedPosition());

			if (box.isNull()) return;

			Ogre::Vector3 vec = box.getSize();

			float width = sqrt(vec.x*vec.x + vec.z*vec.z); // само?длинно?- диагонал?(если крутит?модель)
			float len2 = width / mCamera->getAspectRatio();
			float height = vec.y;
			float len1 = height;
			if (len1 < len2) len1 = len2;
			len1 /= 0.86; // [sqrt(3)/2] for 60 degrees field of view
			// цент?объект?по вертикал?+ отъехать та? чтоб?влезла ближ?¤ гран?BoundingBox'?+ чуть ввер??ещ?наза?дл¤ красот?
			Ogre::Vector3 result = box.getCenter() + Ogre::Vector3(0, 0, vec.z/2 + len1) + Ogre::Vector3(0, height*0.1, len1*0.2);
			Ogre::Vector3 look = Ogre::Vector3(0, box.getCenter().y /*+ box.getCenter().y * (1-mCurrentScale)*/, 0);

			mCameraNode->setPosition(result);
			mCameraNode->lookAt(look, Ogre::Node::TS_WORLD);
		}
	}
Esempio n. 5
0
void SelectionHandler::onSelect(const Picked& obj)
{
  ROS_DEBUG("Selected 0x%08x", obj.handle);

  V_AABB aabbs;
  getAABBs(obj, aabbs);

  if (!aabbs.empty())
  {
    Ogre::AxisAlignedBox combined;
    V_AABB::iterator it = aabbs.begin();
    V_AABB::iterator end = aabbs.end();
    for (; it != end; ++it)
    {
      combined.merge(*it);
    }

    createBox(std::make_pair(obj.handle, 0ULL), combined, "RVIZ/Cyan");
  }
}
    bool MiniMapMaker::outputTextures(void)
    {
        // 如果需要(纹理大小改变了或第一次输出文件时),就重建render texture
        if (mNeedRecreate)
        {
            destroy();
            init();
        }

        mTempOutputFileNames.clear();

        static const String TEMP_GROUP_NAME = "#TEMP#";

        // 创建临时的资源组
        Ogre::ResourceGroupManager& rgm = Ogre::ResourceGroupManager::getSingleton();
        rgm.addResourceLocation(mPath, "FileSystem", TEMP_GROUP_NAME, false);

        // 合并所有物体的包围盒
        Ogre::AxisAlignedBox aabb;
        Ogre::SceneManager::MovableObjectIterator itm =
            mManipulator->getSceneManager()->getMovableObjectIterator(Ogre::EntityFactory::FACTORY_TYPE_NAME);
        while (itm.hasMoreElements())
        {
            Ogre::MovableObject* movable = itm.getNext();
            aabb.merge(movable->getWorldBoundingBox(true));
        }

        mCamera->setFarClipDistance(mCamera->getNearClipDistance() + 2 * (aabb.getMaximum().y - aabb.getMinimum().y ));
        mCamera->setNearClipDistance(mTileSize/2);

        // 设置摄像机的高度
        Real yPos = mCamera->getNearClipDistance() + aabb.getMaximum().y;
        
        TerrainData* terrainData = mManipulator->getTerrainData();
        assert (terrainData);

        float terrainHeight = terrainData->mMaxZ - terrainData->mMinZ;
        float terrainWidth = terrainData->mMaxX - terrainData->mMinX;

        // 投影的真正面积
        Real projectSize = 0.0f;

        // 最终切割成小块纹理的块数
        int xIndex = 0;
        int zIndex = 0;

        Ogre::Vector3 originPoint(Ogre::Vector3::ZERO);

        if (mUseRealCameraAngle)
        {
            float outerSquareWidth = 0.0f;
            float outerSquareHeight = 0.0f;

            Ogre::Radian alphaAngle = Ogre::Math::ATan( Ogre::Math::Abs(mMoveZDir.z / mMoveZDir.x) );

            switch (mCameraDirQuadrant)
            {
            case WestNorth :
                {
                    float leftWidth = Ogre::Math::Sin(alphaAngle) * terrainHeight;
                    float rightWidth = Ogre::Math::Cos(alphaAngle) * terrainWidth;
                    outerSquareWidth = leftWidth + rightWidth;

                    float topHeight = Ogre::Math::Cos(alphaAngle) * terrainHeight;
                    float bottomHeight = Ogre::Math::Sin(alphaAngle) * terrainWidth;

                    outerSquareHeight = topHeight + bottomHeight;

                    originPoint = Ogre::Vector3(terrainData->mMinX,0,terrainData->mMinZ) +
                        (-mMoveZDir * leftWidth);

                    float projectOffset = yPos / Ogre::Math::Tan(mCamDirAngle);

                    originPoint.x += (mInvertCameraDir * projectOffset ).x;
                    originPoint.z += (mInvertCameraDir * projectOffset ).z;

                    break;
                }
            case EastNorth :
                {
                    float leftWidth = Ogre::Math::Cos(alphaAngle) * terrainWidth;
                    float rightWidth = Ogre::Math::Sin(alphaAngle) * terrainHeight;
                    outerSquareWidth = leftWidth + rightWidth;

                    float topHeight = Ogre::Math::Cos(alphaAngle) * terrainHeight;
                    float bottomHeight = Ogre::Math::Sin(alphaAngle) * terrainWidth;

                    outerSquareHeight = topHeight + bottomHeight;

                    originPoint = Ogre::Vector3(terrainData->mMaxX,0,terrainData->mMinZ) +
                        (-mMoveZDir * leftWidth);

                    float projectOffset = yPos / Ogre::Math::Tan(mCamDirAngle);

                    originPoint.x += (mInvertCameraDir * projectOffset ).x;
                    originPoint.z += (mInvertCameraDir * projectOffset ).z;

                    break;
                }
            case EastSouth :
                {
                    float leftWidth = Ogre::Math::Sin(alphaAngle) * terrainHeight;
                    float rightWidth = Ogre::Math::Cos(alphaAngle) * terrainWidth;
                    outerSquareWidth = leftWidth + rightWidth;

                    float topHeight = Ogre::Math::Sin(alphaAngle) * terrainWidth;
                    float bottomHeight = Ogre::Math::Cos(alphaAngle) * terrainHeight;

                    outerSquareHeight = topHeight + bottomHeight;

                    originPoint = Ogre::Vector3(terrainData->mMaxX,0,terrainData->mMaxZ) +
                        (-mMoveZDir * topHeight);

                    float projectOffset = yPos / Ogre::Math::Tan(mCamDirAngle);

                    originPoint.x += (mInvertCameraDir * projectOffset ).x;
                    originPoint.z += (mInvertCameraDir * projectOffset ).z;

                    break;
                }
            case WestSouth :
                {
                    float leftWidth = Ogre::Math::Sin(alphaAngle) * terrainHeight;
                    float rightWidth = Ogre::Math::Cos(alphaAngle) * terrainWidth;
                    outerSquareWidth = leftWidth + rightWidth;

                    float topHeight = Ogre::Math::Sin(alphaAngle) * terrainWidth;
                    float bottomHeight = Ogre::Math::Cos(alphaAngle) * terrainHeight;

                    outerSquareHeight = topHeight + bottomHeight;

                    originPoint = Ogre::Vector3(terrainData->mMinX,0,terrainData->mMaxZ) +
                        (-mMoveZDir * rightWidth);

                    float projectOffset = yPos / Ogre::Math::Tan(mCamDirAngle);

                    originPoint.x += (mInvertCameraDir * projectOffset ).x;
                    originPoint.z += (mInvertCameraDir * projectOffset ).z;

                    break;
                }

            default:
                {
                    OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR,
                        " wrong camera dir " + Ogre::StringConverter::toString(mCameraDir),
                        "MiniMapMaker::outputTextures");

                    break;
                }
            }

            // 计算投影的长度
            Real factor = Ogre::Math::Sin(mCamDirAngle);

            if (factor > 0.0f && factor != 1.0f)
                projectSize = mTileSize / factor;

            // 根据当前场景的大小,计算需要的分块数
            xIndex = Ogre::Math::Ceil( (outerSquareWidth) / mTileSize ) + 1;
            zIndex = Ogre::Math::Ceil( (outerSquareHeight) / projectSize ) + 1;
        }
        else
        {
            xIndex = Ogre::Math::Ceil( (terrainData->mMaxX - terrainData->mMinX) / mTileSize ) + 1;
            zIndex = Ogre::Math::Ceil( (terrainData->mMaxZ - terrainData->mMinZ) / mTileSize ) + 1;

            originPoint.x = terrainData->mMinX;
            originPoint.z = terrainData->mMinZ;
        }

        // 计算最终的mini map的大小
        uint miniMapWidth = xIndex * mTexWidth;
        uint miniMapHeight = zIndex * mTexHeight;

        if ( miniMapWidth > 10000 || miniMapHeight > 10000 )
        {
            mLastErrorString = "texture size is out of range!";
            return false;
        }
        // 创建mini map所需的内存空间
        uchar* miniMapData = new uchar[miniMapWidth * miniMapHeight * Ogre::PixelUtil::getNumElemBytes(mOutPutFormat)];

        //// 初始的摄像机位置
        Real xPos = originPoint.x;
        Real zPos = originPoint.z;

        for ( int i=0; i<xIndex; ++i )
        {
            for ( int j=0; j<zIndex; ++j )
            {
                // 设置摄像机位置,并更新render texture的内容
                mCamera->setPosition(xPos, yPos, zPos);
                mRenderTexture->update();

                String fileName = mPath + mSceneBaseName + Ogre::StringConverter::toString(i)
                    + "_" + Ogre::StringConverter::toString(j) + "." + mTexExtension;

                // 输出小纹理文件
                mRenderTexture->writeContentsToFile(fileName);

                mTempOutputFileNames.push_back(fileName);

                // 读取刚创建的纹理
                Ogre::Image* tempImage = new Ogre::Image;
                
                tempImage->load(mSceneBaseName + Ogre::StringConverter::toString(i)
                    + "_" + Ogre::StringConverter::toString(j) + "." + mTexExtension, TEMP_GROUP_NAME);

                // 获取render texture中的内容
                uchar* tempImageData = tempImage->getData();

                // 定位在mini map中的左上角
                uint miniMapIndex = ( j * mTexHeight * miniMapWidth + i * mTexWidth ) * Ogre::PixelUtil::getNumElemBytes(mOutPutFormat);

                uchar* startData = miniMapData + miniMapIndex;

                for ( size_t height = 0; height < tempImage->getHeight(); ++height )
                {
                    for ( size_t width = 0; width < tempImage->getWidth(); ++width )
                    {
                        memcpy(startData, tempImageData, Ogre::PixelUtil::getNumElemBytes(mOutPutFormat));

                        startData += Ogre::PixelUtil::getNumElemBytes(mOutPutFormat);
                        tempImageData += Ogre::PixelUtil::getNumElemBytes( tempImage->getFormat() );
                    }
                    startData += (miniMapWidth - tempImage->getWidth()) * Ogre::PixelUtil::getNumElemBytes(mOutPutFormat);
                }

                delete tempImage;

                // 移动摄像机的z坐标
                if (mUseRealCameraAngle)
                {
                    zPos += (mInvertCameraDir * (projectSize)).z;
                    xPos += (mInvertCameraDir * (projectSize)).x;
                }
                else
                   zPos += mTileSize;
            }
            
            if (mUseRealCameraAngle)
            {
                xPos = originPoint.x;
                zPos = originPoint.z;

                xPos += (mMoveZDir * (mTileSize) * (i+1)).x;
                zPos += (mMoveZDir * (mTileSize) * (i+1)).z;
            }
            else
            {
                // 操作完每一列之后,重置摄像机的z坐标
                zPos = terrainData->mMinZ;

                // 移动摄像机的x坐标
                xPos += mTileSize;
            }
        } 

        // 保存mini map并输出
        Ogre::Image* miniMapImage = new Ogre::Image;
        miniMapImage->loadDynamicImage(miniMapData, miniMapWidth, miniMapHeight, 1, mOutPutFormat, true);

        miniMapImage->save(mPath + mOutFileName + "." + mTexExtension);

        delete miniMapImage;

        rgm.destroyResourceGroup(TEMP_GROUP_NAME);

        return true;
    }
Esempio n. 7
0
	void RenderBoxWrap::updateViewport()
	{
		// при нуле вылетает
		if ((mRenderBox->getWidth() <= 1) || (mRenderBox->getHeight() <= 1) ) return;

		if ((nullptr != mEntity) && (nullptr != mRttCam)) {
			// не ¤сно, нужно ли раст¤гивать камеру, установленную юзером
			mRttCam->setAspectRatio((float)mRenderBox->getWidth() / (float)mRenderBox->getHeight());

			//System::Console::WriteLine("Width {0}, Height {1}", getWidth(), getHeight());

			// вычисл¤ем рассто¤ние, чтобы был виден весь объект
			Ogre::AxisAlignedBox box;// = mNode->_getWorldAABB();//mEntity->getBoundingBox();

			VectorEntity::iterator iter = mVectorEntity.begin();

			while (iter != mVectorEntity.end())
			{
				box.merge((*iter)->getBoundingBox().getMinimum() + (*iter)->getParentSceneNode()->_getDerivedPosition());
				box.merge((*iter)->getBoundingBox().getMaximum() + (*iter)->getParentSceneNode()->_getDerivedPosition());
				iter++;
			}

			if (box.isNull()) return;

			//box.scale(Ogre::Vector3(1.41f,1.41f,1.41f));

			//System::Console::WriteLine("Minimum({0}), Maximum({1})",
			//	gcnew System::String(Ogre::StringConverter::toString(box.getMinimum()).c_str()),
			//	gcnew System::String(Ogre::StringConverter::toString(box.getMaximum()).c_str()));

			//box.getCenter();
			Ogre::Vector3 vec = box.getSize();

			// коррекци¤ под левосторонюю систему координат с осью Z направленную вверх
			#ifdef LEFT_HANDED_CS_UP_Z

				float width = sqrt(vec.x*vec.x + vec.y*vec.y); // самое длинное - диагональ (если крутить модель)
				float len2 = width; // mRttCam->getAspectRatio();
				float height = vec.z;
				float len1 = height;
				if (len1 < len2) len1 = len2;
				len1 /= 0.86; // [sqrt(3)/2] for 60 degrees field of view
				// центр объекта по вертикали + отъехать так, чтобы влезла ближн¤¤ грань BoundingBox'а + чуть вверх и еще назад дл¤ красоты
				Ogre::Vector3 result = box.getCenter() - Ogre::Vector3(vec.y/2 + len1, 0, 0) - Ogre::Vector3(len1*0.2, 0, -height*0.1);
				result.x *= mCurrentScale;
				mCamNode->setPosition(result);

				Ogre::Vector3 x = Ogre::Vector3(0, 0, box.getCenter().z + box.getCenter().z * (1-mCurrentScale)) - mCamNode->getPosition();
				Ogre::Vector3 y = Ogre::Vector3(Ogre::Vector3::UNIT_Z).crossProduct(x);
				Ogre::Vector3 z = x.crossProduct(y);
				mCamNode->setOrientation(Ogre::Quaternion(
					x.normalisedCopy(),
					y.normalisedCopy(),
					z.normalisedCopy()));

			#else

				float width = sqrt(vec.x*vec.x + vec.z*vec.z); // самое длинное - диагональ (если крутить модель)
				float len2 = width / mRttCam->getAspectRatio();
				float height = vec.y;
				float len1 = height;
				if (len1 < len2) len1 = len2;
				len1 /= 0.86; // [sqrt(3)/2] for 60 degrees field of view
				// центр объекта по вертикали + отъехать так, чтобы влезла ближн¤¤ грань BoundingBox'а + чуть вверх и еще назад дл¤ красоты
				Ogre::Vector3 result = box.getCenter() + Ogre::Vector3(0, 0, vec.z/2 + len1) + Ogre::Vector3(0, height*0.1, len1*0.2);
				result.z *= mCurrentScale;
				Ogre::Vector3 look = Ogre::Vector3(0, box.getCenter().y /*+ box.getCenter().y * (1-mCurrentScale)*/, 0);

				mCamNode->setPosition(result);
				mCamNode->lookAt(look, Ogre::Node::TS_WORLD);

			#endif
		}
	}
Esempio n. 8
0
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
{
    Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
    assert(insert);

    Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
    NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(insert, NULL, mesh);
    for(size_t i = 0;i < entities.mEntities.size();i++)
    {
        const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox();
        bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(),
                                          insert->_getDerivedPosition() + tmp.getMaximum())
        );
    }
    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 transparent = false;
    for(size_t i = 0;i < entities.mEntities.size();i++)
    {
        Ogre::Entity *ent = entities.mEntities[i];
        for (unsigned int i=0; i<ent->getNumSubEntities(); ++i)
        {
            Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial();
            Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
            while (techIt.hasMoreElements())
            {
                Ogre::Technique* tech = techIt.getNext();
                Ogre::Technique::PassIterator passIt = tech->getPassIterator();
                while (passIt.hasMoreElements())
                {
                    Ogre::Pass* pass = passIt.getNext();

                    if (pass->getDepthWriteEnabled() == false)
                        transparent = true;
                }
            }
        }
    }

    if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent)
    {
        for(size_t i = 0;i < entities.mEntities.size();i++)
        {
            Ogre::Entity *ent = entities.mEntities[i];

            ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
            ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
            ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
        }
    }
    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(transparent ? RQG_Alpha : RQG_Main);

        for(size_t i = 0;i < entities.mEntities.size();i++)
        {
            Ogre::Entity *ent = entities.mEntities[i];
            insert->detachObject(ent);
            sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());

            mRenderer.getScene()->destroyEntity(ent);
        }
    }
}
Esempio n. 9
0
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());
    }
}
Esempio n. 10
0
void AssetLoader::readModel(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* scnNode, const aiScene* scene, aiNode* nd)
{
	for (size_t n = 0; n < nd->mNumChildren; n++) 
	{	
		aiNode* cnd = nd->mChildren[n];
		Ogre::SceneNode* cnode = createChildSceneNodeWithTransform(scnNode, cnd);

		for (size_t i = 0; i < cnd->mNumMeshes; i++) {
			aiMesh* m = scene->mMeshes[cnd->mMeshes[i]];	
			aiMaterial* mat = scene->mMaterials[m->mMaterialIndex];

			std::string nodeName = getFullPathName(cnd);
			Ogre::MaterialPtr omat = createMaterial(Ogre::String(nodeName), m->mMaterialIndex, mat);

			aiVector3D* vec  = m->mVertices;
			aiVector3D* norm = m->mNormals;
			aiVector3D* uv   = m->mTextureCoords[0];
			aiColor4D*  vcol = NULL;	
			if (m->HasVertexColors(0)) vcol = m->mColors[0];

			// 頂点情報の読み込み
			Ogre::AxisAlignedBox aab;
			Ogre::ManualObject* mobj = new Ogre::ManualObject(nodeName+"_MObj");
			mobj->begin(omat->getName());
			//mobj->begin("Ogre/Skin");
			for (size_t n = 0; n < m->mNumVertices; n ++) {
				Ogre::Vector3 position(vec->x, vec->y, vec->z);
				aab.merge(position);

				mobj->position(vec->x, vec->y, vec->z); 
				vec++;  

				mobj->normal(norm->x, norm->y, norm->z);
				norm++; 

				if (uv)   { 
					mobj->textureCoord(uv->x, uv->y);        
					uv++;   
				}
				if (vcol) { 
					mobj->colour(vcol->r, vcol->g, vcol->b, vcol->a); 
					vcol++;
				}
			}

			// ポリゴンの構築
			for (size_t n = 0; n < m->mNumFaces; n++) {
				aiFace* face = &m->mFaces[n];
				for (size_t k = 0; k < face->mNumIndices; k++) {
					mobj->index(face->mIndices[k]);
				}
			}
			mobj->end();
			mobj->setBoundingBox(aab);

			Ogre::String meshName(nodeName+"_Mesh");
			mobj->convertToMesh(meshName);
			delete mobj;

			Ogre::String entityName(nodeName+"_Entity");
			std::cout << "entity: " << entityName << std::endl;
			Ogre::Entity* ent = sceneMgr->createEntity(entityName, meshName);
			cnode->attachObject(ent);
		}

		readModel(sceneMgr, cnode, scene, cnd);
	}
}
Esempio n. 11
0
void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectScenePtr objlist, const ESM::Light *light)
{
    const MWWorld::Fallback *fallback = MWBase::Environment::get().getWorld()->getFallback();

    const int clr = light->mData.mColor;
    Ogre::ColourValue color(((clr >> 0) & 0xFF) / 255.0f,
                            ((clr >> 8) & 0xFF) / 255.0f,
                            ((clr >> 16) & 0xFF) / 255.0f);
    const float radius = float(light->mData.mRadius);

    if((light->mData.mFlags&ESM::Light::Negative))
        color *= -1;

    objlist->mLights.push_back(sceneMgr->createLight());
    Ogre::Light *olight = objlist->mLights.back();
    olight->setDiffuseColour(color);

    Ogre::ControllerValueRealPtr src(Ogre::ControllerManager::getSingleton().getFrameTimeSource());
    Ogre::ControllerValueRealPtr dest(OGRE_NEW OEngine::Render::LightValue(olight, color));
    Ogre::ControllerFunctionRealPtr func(OGRE_NEW OEngine::Render::LightFunction(
        (light->mData.mFlags&ESM::Light::Flicker) ? OEngine::Render::LT_Flicker :
        (light->mData.mFlags&ESM::Light::FlickerSlow) ? OEngine::Render::LT_FlickerSlow :
        (light->mData.mFlags&ESM::Light::Pulse) ? OEngine::Render::LT_Pulse :
        (light->mData.mFlags&ESM::Light::PulseSlow) ? OEngine::Render::LT_PulseSlow :
        OEngine::Render::LT_Normal
    ));
    objlist->mControllers.push_back(Ogre::Controller<Ogre::Real>(src, dest, func));

    bool interior = !(mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior());
    bool quadratic = fallback->getFallbackBool("LightAttenuation_OutQuadInLin") ?
                     !interior : fallback->getFallbackBool("LightAttenuation_UseQuadratic");

    // with the standard 1 / (c + d*l + d*d*q) equation the attenuation factor never becomes zero,
    // so we ignore lights if their attenuation falls below this factor.
    const float threshold = 0.03;

    if (!quadratic)
    {
        float r = radius * fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
        float attenuation = fallback->getFallbackFloat("LightAttenuation_LinearValue") / r;
        float activationRange = 1.0f / (threshold * attenuation);
        olight->setAttenuation(activationRange, 0, attenuation, 0);
    }
    else
    {
        float r = radius * fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
        float attenuation = fallback->getFallbackFloat("LightAttenuation_QuadraticValue") / std::pow(r, 2);
        float activationRange = std::sqrt(1.0f / (threshold * attenuation));
        olight->setAttenuation(activationRange, 0, 0, attenuation);
    }

    // If there's an AttachLight bone, attach the light to that, otherwise put it in the center,
    if(objlist->mSkelBase && objlist->mSkelBase->getSkeleton()->hasBone("AttachLight"))
        objlist->mSkelBase->attachObjectToBone("AttachLight", olight);
    else
    {
        Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
        for(size_t i = 0;i < objlist->mEntities.size();i++)
        {
            Ogre::Entity *ent = objlist->mEntities[i];
            bounds.merge(ent->getBoundingBox());
        }

        Ogre::SceneNode *node = bounds.isFinite() ? mInsert->createChildSceneNode(bounds.getCenter())
                                                  : mInsert->createChildSceneNode();
        node->attachObject(olight);
    }
}
Esempio n. 12
0
 void operator()(Ogre::MovableObject *obj)
 {
     mBounds->merge(obj->getWorldBoundingBox(true));
 }