InputGeometry::InputGeometry(std::vector<Ogre::Entity*> sourceMeshes,const Ogre::AxisAlignedBox& tileBounds)
	: _sourceMeshes(sourceMeshes),
	  _numVertices(0),
	  _numTriangles(0),
	  _referenceNode(0),
	  _boundMin(0),
	  _boundMax(0),
	  _normals(0),
	  _vertices(0),
	  _triangles(0)
{
	if(sourceMeshes.empty())
	{
		return;
	}

	Ogre::Entity* ent = sourceMeshes[0];
	_referenceNode = ent->getParentSceneNode()->getCreator()->getRootSceneNode();

	_boundMin = new float[3];
	_boundMax = new float[3];
	Utility::vector3_toFloatPtr(tileBounds.getMinimum(),_boundMin);
	Utility::vector3_toFloatPtr(tileBounds.getMaximum(),_boundMax);

	_convertOgreEntities(tileBounds);

	//eventually add _buildChunkyTriMesh()

}
ConvexVolume::ConvexVolume(Ogre::AxisAlignedBox boundingBox, float offset)
{
    Ogre::Vector3 max = boundingBox.getMaximum();
    Ogre::Vector3 min = boundingBox.getMinimum();

    // Offset bounding box (except height)
    if(offset > 0.01f) {
        max = max + offset*Ogre::Vector3(1,0,1);
        min = min - offset*Ogre::Vector3(1,0,1);
    }

    // Create box verts (in clockwise fashion!!)
    verts[0]= min.x; verts[1]= min.y; verts[2]= max.z;
    verts[3]= max.x; verts[4]= max.y; verts[5]= max.z;
    verts[6]= max.x; verts[7]= max.y; verts[8]= min.z;
    verts[9]= min.x; verts[10]= min.y; verts[11]= min.z;
    nverts = 4; // For rcMarkConvexPoly the verts of the shape need to be in clockwise order

    // Set bounding box limits
    OgreRecast::OgreVect3ToFloatA(min, bmin);
    OgreRecast::OgreVect3ToFloatA(max, bmax);

    // Set height limits
    hmin = min.y;
    hmax = max.y;

    area = SAMPLE_POLYAREA_DOOR;   // You can choose whatever flag you assing to the poly area
}
void InputGeometry::_calculateExtents()
{
	Ogre::Entity* ent = _sourceMeshes[0];
	Ogre::AxisAlignedBox sourceMeshBB = ent->getBoundingBox();
	Ogre::Matrix4 transform;
	transform = _referenceNode->_getFullTransform().inverse() * ent->getParentSceneNode()->_getFullTransform();
	sourceMeshBB.transform(transform);
	Ogre::Vector3 min = sourceMeshBB.getMinimum();
	Ogre::Vector3 max = sourceMeshBB.getMaximum();

	for(auto itr = _sourceMeshes.begin(); itr != _sourceMeshes.end(); ++itr)
	{
		Ogre::Entity* tmpEnt = *itr;

		transform = _referenceNode->_getFullTransform().inverse() * tmpEnt->getParentSceneNode()->_getFullTransform();

		sourceMeshBB = ent->getBoundingBox();
		sourceMeshBB.transform(transform);
		Ogre::Vector3 min2 = sourceMeshBB.getMinimum();
		if(min2.x < min.x)
            min.x = min2.x;
        if(min2.y < min.y)
            min.y = min2.y;
        if(min2.z < min.z)
            min.z = min2.z;

		Ogre::Vector3 max2 = sourceMeshBB.getMaximum();
		if(max2.x > max.x)
            max.x = max2.x;
        if(max2.y > max.y)
            max.y = max2.y;
        if(max2.z > max.z)
            max.z = max2.z;
	}

	if(!_boundMin)
	{
		_boundMin = new float[3];
	}
	if(!_boundMax)
	{
		_boundMax = new float[3];
	}
	Utility::vector3_toFloatPtr(min,_boundMin);
	Utility::vector3_toFloatPtr(max,_boundMax);
}
Beispiel #4
0
 void World::convertBounds(Ogre::AxisAlignedBox& bounds)
 {
     switch (mAlign)
     {
     case Align_XY:
         return;
     case Align_XZ:
         convertPosition(bounds.getMinimum());
         convertPosition(bounds.getMaximum());
         // Because we changed sign of Z
         std::swap(bounds.getMinimum().z, bounds.getMaximum().z);
         return;
     case Align_YZ:
         convertPosition(bounds.getMinimum());
         convertPosition(bounds.getMaximum());
         return;
     }
 }
void GPUBillboardSet::updateBoundingBoxAndSphereFromBillboards(const std::vector<PhotoSynth::Vertex>& vertices)
{
	Ogre::AxisAlignedBox box = calculateBillboardsBoundingBox(vertices);
	setBoundingBox(box);

	Ogre::Vector3 vmax = box.getMaximum();
	Ogre::Vector3 vmin = box.getMinimum();
	Ogre::Real sqLen = std::max(vmax.squaredLength(), vmin.squaredLength());
	mBBRadius = Ogre::Math::Sqrt(sqLen);
}
Beispiel #6
0
ModelBlock::ModelBlock(Ogre::SceneNode* baseNode,const  Carpenter::BuildingBlock* buildingBlock, Model::Model* model, Construction* construction)
: mBuildingBlock(buildingBlock)
, mModel(model)
, mModelNode(0)
, mConstruction(construction)
{


	mNode = baseNode->createChildSceneNode(Convert::toOgre(buildingBlock->getPosition()), Convert::toOgre(buildingBlock->getOrientation()));


	mPointBillBoardSet = mNode->getCreator()->createBillboardSet( std::string("__construction_") + construction->getBluePrint()->getName() + "_" + buildingBlock->getName() + "_billboardset__" + mNode->getName());
	mPointBillBoardSet->setDefaultDimensions(1, 1);
	mPointBillBoardSet->setMaterialName("carpenter/flare");
	mPointBillBoardSet->setVisible(false);
//	Ogre::SceneNode* aNode = EmberOgre::getSingleton().getSceneManager()->getRootSceneNode()->createChildSceneNode();
	mNode->attachObject(mPointBillBoardSet);


	if (model) {
		JesusPickerObject* pickerObject = new JesusPickerObject(this, 0);
		model->setUserObject(pickerObject);


		mModelNode = mNode->createChildSceneNode();
		mModelNode->attachObject(model);
		model->setQueryFlags(Jesus::CM_MODELBLOCK);

		//only autoscale the model if we've not set the scale in the modeldefinition
		//TODO: it would of course be best if all models were correctly scaled and this code could be removed
		if (model->getDefinition()->getScale() == 0) {
			const Ogre::AxisAlignedBox ogreBoundingBox = model->getBoundingBox();
			const Ogre::Vector3 ogreMax = ogreBoundingBox.getMaximum();
			const Ogre::Vector3 ogreMin = ogreBoundingBox.getMinimum();


			const WFMath::AxisBox<3> wfBoundingBox = buildingBlock->getBuildingBlockSpec()->getBlockSpec()->getBoundingBox();
			const WFMath::Point<3> wfMax = wfBoundingBox.highCorner();
			const WFMath::Point<3> wfMin = wfBoundingBox.lowCorner();

			Ogre::Real scaleX;
			Ogre::Real scaleY;
			Ogre::Real scaleZ;

			scaleX = fabs((wfMax.x() - wfMin.x()) / (ogreMax.x - ogreMin.x));
			scaleY = fabs((wfMax.z() - wfMin.z()) / (ogreMax.y - ogreMin.y));
			scaleZ = fabs((wfMax.y() - wfMin.y()) / (ogreMax.z - ogreMin.z));

			mModelNode->setScale(scaleX, scaleY, scaleZ);
		}

	}

}
void OgreDetourTileCache::unloadTiles(const Ogre::AxisAlignedBox &areaToUpdate)
{
    // Determine which navmesh tiles have to be removed
    float bmin[3], bmax[3];
    OgreRecast::OgreVect3ToFloatA(areaToUpdate.getMinimum(), bmin);
    OgreRecast::OgreVect3ToFloatA(areaToUpdate.getMaximum(), bmax);
    dtCompressedTileRef touched[DT_MAX_TOUCHED_TILES];
    int ntouched = 0;
    m_tileCache->queryTiles(bmin, bmax, touched, &ntouched, DT_MAX_TOUCHED_TILES);

    // Remove tiles
    for (int i = 0; i < ntouched; ++i)
    {
        removeTile(touched[i]);
    }
}
Beispiel #8
0
void Player::setupNodes (Ogre::SceneManager* sceneManager)
{
    // Create the nodes
    mPlayerNode         = sceneManager->getRootSceneNode()->createChildSceneNode("PlayerNode");
    mPlayerCameraNode   = mPlayerNode->createChildSceneNode("PlayerCameraNode");
    mCharacterNode      = mPlayerNode->createChildSceneNode("PlayerCharacterNode");
    mTargettingPathNode = mPlayerNode->createChildSceneNode("PlayerPathNode");
    mTargettingEndNode  = sceneManager->getRootSceneNode()->createChildSceneNode("TargettingEndNode");
    mTargettingPathNode->setVisible(false);
    mPlayerCameraNode->setPosition(0, 100, 200);


    // Add the entities
    // Add player
    Ogre::Entity* playerEntity = sceneManager->createEntity("PlayerCharacter", "potato.mesh");
    Ogre::AxisAlignedBox bb = playerEntity->getBoundingBox();
    mPlayerHeight = (bb.getMaximum().y - bb.getMinimum().y) * 0.1f * 0.5f;
    mCharacterNode->attachObject(playerEntity);
    mCharacterNode->setScale(0.1f, 0.1f, 0.1f);
    mCharacterNode->setPosition(0, 0, 0);

    // Add target marker
    mTargettingEndNode = sceneManager->getRootSceneNode()->createChildSceneNode("TargetNode");
    Ogre::Entity* targetEntity = sceneManager->createEntity("TargetEntity", "sphere.mesh");
    mTargettingEndNode->attachObject(targetEntity);
    targetEntity = sceneManager->createEntity("TargetEntity2", "column.mesh");
    mTargettingEndNode->attachObject(targetEntity);
    mTargettingEndNode->setScale(0.1f, 0.1f, 0.1f);
    mTargettingEndNode->setPosition(0, 0, 0);


    // Billboard set
    /*mTargettingEndBBS = sceneManager->createBillboardSet("TargetBillboardSet", 2);
    sceneManager->getRootSceneNode()->attachObject(mTargettingEndBBS);
    mTargettingEndBBS->setMaterialName("Examples/Flare");
    mTargettingEndBBS->setVisible(true);
    mTargettingEndBBS->createBillboard(0, 300, 0, Ogre::ColourValue(0.5f, 0.6f, 1.0f));
    mTargettingEndBBS->setDefaultDimensions(100, 100);
    mTargettingEndBBS->setBillboardType(Ogre::BBT_ORIENTED_COMMON);
    mTargettingEndBBS->setCommonUpVector(Ogre::Vector3(0, 1, 0));*/
}
void OgreDetourTileCache::buildTiles(InputGeom *inputGeom, const Ogre::AxisAlignedBox *areaToUpdate)
{
    // Use bounding box from inputgeom if no area was explicitly specified
    Ogre::AxisAlignedBox updateArea;
    if(!areaToUpdate)
        updateArea = inputGeom->getBoundingBox();
    else
        updateArea = *areaToUpdate;

    // Reduce bounding area a little with one cell in size, to be sure that if it was already tile-aligned, we don't select an extra tile
    updateArea.setMinimum( updateArea.getMinimum() + Ogre::Vector3(m_cellSize, 0, m_cellSize) );
    updateArea.setMaximum( updateArea.getMaximum() - Ogre::Vector3(m_cellSize, 0, m_cellSize) );

    // Select tiles to build or rebuild (builds a tile-aligned BB)
    TileSelection selection = getTileSelection(updateArea);


    // Debug drawing of bounding area that is updated
    // Remove previous debug drawn bounding box of rebuilt area
    if(mDebugRebuiltBB) {
        mDebugRebuiltBB->detachFromParent();
        m_recast->m_pSceneMgr->destroyManualObject(mDebugRebuiltBB);
        mDebugRebuiltBB = NULL;
    }
    if(DEBUG_DRAW_REBUILT_BB)
        mDebugRebuiltBB = InputGeom::drawBoundingBox(selection.bounds, m_recast->m_pSceneMgr);


    int tilesToBuildX = (selection.maxTx - selection.minTx)+1;  // Tile ranges are inclusive
    int tilesToBuildY = (selection.maxTy - selection.minTy)+1;
    if(tilesToBuildX * tilesToBuildY > 5)
        Ogre::LogManager::getSingletonPtr()->logMessage("Building "+Ogre::StringConverter::toString(tilesToBuildX)+" x "+Ogre::StringConverter::toString(tilesToBuildY)+" navmesh tiles.");

    // Build tiles
    for (int ty = selection.minTy; ty <= selection.maxTy; ty++) {
        for (int tx = selection.minTx; tx <= selection.maxTx; tx++) {
            buildTile(tx, ty, inputGeom);
        }
    }
}
void MaterialEditorFrame::OnFileOpen(wxCommandEvent& event)
{
	wxFileDialog * openDialog = new wxFileDialog(this, wxT("Choose a file to open"), wxEmptyString, wxEmptyString,
		wxT("All Ogre Files (*.material;*.mesh;*.program;*.cg;*.vert;*.frag)|*.material;*.mesh;*.program;*.cg;*.vert;*.frag|Material Files (*.material)|*.material|Mesh Files (*.mesh)|*.mesh|Program Files (*.program)|*.program|Cg Files (*.cg)|*.cg|GLSL Files(*.vert; *.frag)|*.vert;*.frag|All Files (*.*)|*.*"));

	if(openDialog->ShowModal() == wxID_OK)
	{
		wxString path = openDialog->GetPath();
		if(path.EndsWith(wxT(".material")) || path.EndsWith(wxT(".program")))
		{
			MaterialScriptEditor* editor = new MaterialScriptEditor(EditorManager::getSingletonPtr()->getEditorNotebook());
			editor->loadFile(path);
			int index = (int)path.find_last_of('\\');
			if(index == -1) index = (int)path.find_last_of('/');
			editor->setName((index != -1) ? path.substr(index + 1, path.Length()) : path);

			EditorManager::getSingletonPtr()->openEditor(editor);
		}
		else if(path.EndsWith(wxT(".cg")))
		{
			CgEditor* editor = new CgEditor(EditorManager::getSingletonPtr()->getEditorNotebook());
			editor->loadFile(path);
			int index = (int)path.find_last_of('\\');
			if(index == -1) index = (int)path.find_last_of('/');
			editor->setName((index != -1) ? path.substr(index + 1, path.Length()) : path);

			EditorManager::getSingletonPtr()->openEditor(editor);
		}
		else if(path.EndsWith(wxT(".mesh")))
		{
			Ogre::SceneManager *sceneMgr = wxOgre::getSingleton().getSceneManager();
			Ogre::Camera *camera = wxOgre::getSingleton().getCamera();

			if(mEntity)
			{
				sceneMgr->getRootSceneNode()->detachObject(mEntity);
				sceneMgr->destroyEntity(mEntity);
				mEntity = 0;
			}
			
			static int meshNumber = 0;
			Ogre::String meshName = Ogre::String("Mesh") + Ogre::StringConverter::toString(meshNumber++);

			int index = (int)path.find_last_of('\\');
			if(index == -1) index = (int)path.find_last_of('/');
			wxString mesh = (index != -1) ? path.substr(index + 1, path.Length()) : path;

			mEntity = sceneMgr->createEntity(meshName, mesh.GetData());
			sceneMgr->getRootSceneNode()->attachObject(mEntity);

			Ogre::AxisAlignedBox box = mEntity->getBoundingBox();
			Ogre::Vector3 minPoint = box.getMinimum();
			Ogre::Vector3 maxPoint = box.getMaximum();
			Ogre::Vector3 size = box.getSize();

			wxOgre::getSingleton().setZoomScale(max(size.x, max(size.y, size.z)));
			wxOgre::getSingleton().resetCamera();

			Ogre::Vector3 camPos;
			camPos.x = minPoint.x + (size.x / 2.0);
			camPos.y = minPoint.y + (size.y / 2.0);
			Ogre::Real width = max(size.x, size.y);
			camPos.z = (width / tan(camera->getFOVy().valueRadians())) + size.z / 2;

			wxOgre::getSingleton().getCamera()->setPosition(camPos);
			wxOgre::getSingleton().getCamera()->lookAt(0,0,0);

			wxOgre::getSingleton().getLight()->setPosition(maxPoint * 2);
		}
	}
}
Beispiel #11
0
void
Terrain::buildGeometry(Ogre::SceneNode* parent, bool editable)
{
    clearGeometry();	

    assert(parent);

    // NB: We must adjust world geometry bounding box, especially for OctreeSceneManager
    Ogre::AxisAlignedBox aabb = mData->getBoundBox();
    Ogre::Vector3 centre = aabb.getCenter();
    const Ogre::Vector3 adjust(2000, 10000, 2000);
    const Ogre::Real scale = 1.5f;
    aabb.setExtents(
        (aabb.getMinimum() - centre) * scale + centre - adjust,
        (aabb.getMaximum() - centre) * scale + centre + adjust);
    parent->getCreator()->setOption("Size", &aabb);

    mEditable = editable;

    if (!mData->mXSize || !mData->mZSize)
    {
        // Do nothing if it's empty terrain.
        return;
    }

    // Prepare atlas texture
    for (size_t pixmapId = 0, numPixmap = mData->mPixmaps.size(); pixmapId < numPixmap; ++pixmapId)
    {
        _getPixmapAtlasId(pixmapId);
    }

	prepareLightmapTexture();

    int depth = mData->mZSize;
    int width = mData->mXSize;
    int tileSize = mData->mTileSize;
    int numTilePerX = mData->mNumTilePerX;
    int numTilePerZ = mData->mNumTilePerZ;

    if (mEditable)
    {
        mGridTypeInfos.resize(2);
        mGridTypeInfos[0].material.setNull();
        mGridTypeInfos[1].material = Ogre::MaterialManager::getSingleton().getByName(
            "FairyEditor/GridType");
    }
    else
    {
        _initIndexBuffer(tileSize * tileSize);
    }

    mTiles.reserve(numTilePerX * numTilePerZ);
    for (int z = 0; z < numTilePerZ; ++z)
    {
        for (int x = 0; x < numTilePerX; ++x)
        {
            // Create the tile
            int tileX = x * tileSize;
            int tileZ = z * tileSize;
            int tileWidth = std::min(width - tileX, tileSize);
            int tileDepth = std::min(depth - tileZ, tileSize);
            TerrainTile* tile;
			if (mEditable)
				tile = new TerrainTileEditable(parent, this, tileX, tileZ, tileWidth, tileDepth);
			else
				tile = new TerrainTileOptimized(parent, this, tileX, tileZ, tileWidth, tileDepth);

            // Use the render queue that the world geometry associated with.
            tile->setRenderQueueGroup(parent->getCreator()->getWorldGeometryRenderQueue());

            // Attach it to the aux data
            mTiles.push_back(tile);
        }
    }
}
    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;
    }
float SimpleVehicle::getHeight() const 
{
    Ogre::AxisAlignedBox aab = mCreature->getActor()->getPhysicalThing()->_getBody()->getCollision()->getAABB();
    return aab.getMaximum().y - aab.getMinimum().y;
}
float SimpleVehicle::getRadius() const 
{
	// this is only the radius in x axis, but i think, this is the value that should be used here
    Ogre::AxisAlignedBox aab = mCreature->getActor()->getPhysicalThing()->_getBody()->getCollision()->getAABB();
    return(aab.getMaximum().x - aab.getMinimum().x)/2;
}
Beispiel #15
0
void World::setWorldSize( const Ogre::AxisAlignedBox& box )
{
    NewtonSetWorldSize( m_world, (float*)&box.getMinimum(), (float*)&box.getMaximum() );
    m_limits = box;
}
Beispiel #16
0
Ogre::Vector3 Cube::getEntityCenter(Ogre::Entity& _entity)
{
    Ogre::AxisAlignedBox boundingBox = _entity.getBoundingBox();
    Ogre::Vector3 point = ( boundingBox.getMaximum() - boundingBox.getMinimum() ) /2;
    return point;
}
void CTerrainWalkingView::OnTimer(UINT_PTR nIDEvent)
{
	Ogre::Quaternion Quaternion;
	CEngine *Engine = ((CTerrainWalkingApp*)AfxGetApp())->m_Engine;		
	Ogre::Root *Root = Engine->GetRoot();
	Ogre::SceneNode *RobotNode = Root->getSceneManager("Walking")->getSceneNode("Robot");
	Ogre::Entity *RobotEntity = Root->getSceneManager("Walking")->getEntity("Robot");
	Ogre::AxisAlignedBox RobotBox = RobotEntity->getBoundingBox();

	Ogre::Entity *TopographyEntity = Root->getSceneManager("Walking")->getEntity("Topography");

	Ogre::AxisAlignedBox TopographyBox = TopographyEntity->getBoundingBox();
		
	Ogre::Vector3 Start = TopographyBox.getMinimum();
	Ogre::Vector3 Finish = TopographyBox.getMaximum();

	double x = Start[0] + (Finish[0] - Start[0]) * m_RelativeDistance;
	double y = Start[1] + (Finish[1] - Start[1]) * m_RelativeDistance;
	double z = Start[2] + (Finish[2] - Start[2]) * m_RelativeDistance;
	
	Ogre::Vector3 Elevation(x, y, z);
	Ogre::Vector3 CameraMove;

	switch (nIDEvent)
	{
		case 1:

			m_Animation->addTime(0.01);
			m_RelativeDistance += 0.01;

			if (m_CollisionTools->collidesWithEntity(Elevation, Ogre::Vector3(x,y - 1,z), Ogre::Vector3(x,y + 1,z), 100.0f, 0.0f, 4294967295))
			{
				x = Elevation[0];
				y = Elevation[1] + RobotBox.getSize()[1];
				z = Elevation[2];
			}

			RobotNode->setPosition(x, y, z);
			m_Camera->lookAt(x, y, z);
			
			if (m_RelativeDistance > 1.0)
			  KillTimer(1);

		break;

		case 2:

			CameraMove[0] = -100;
			CameraMove[1] = 0;
			CameraMove[2] = 0;
			m_Camera->moveRelative(CameraMove);

		break;

		case 3:

			CameraMove[0] = 0;
			CameraMove[1] = 100;
			CameraMove[2] = 0;
			m_Camera->moveRelative(CameraMove);

			break;

		case 4:

			CameraMove[0] = 100;
			CameraMove[1] = 0;
			CameraMove[2] = 0;
			m_Camera->moveRelative(CameraMove);

			break;

		case 5:

			CameraMove[0] = 0;
			CameraMove[1] = -100;
			CameraMove[2] = 0;
			m_Camera->moveRelative(CameraMove);

			break;
	}

	Root->renderOneFrame();
	CView::OnTimer(nIDEvent);
}
void CTerrainWalkingView::EngineSetup(void)
{
	Ogre::Root *Root = ((CTerrainWalkingApp*)AfxGetApp())->m_Engine->GetRoot();
	Ogre::SceneManager *SceneManager = NULL;
	SceneManager = Root->createSceneManager(Ogre::ST_GENERIC, "Walking");
 
    //
    // Create a render window
    // This window should be the current ChildView window using the externalWindowHandle
    // value pair option.
    //

    Ogre::NameValuePairList parms;
    parms["externalWindowHandle"] = Ogre::StringConverter::toString((long)m_hWnd);
    parms["vsync"] = "true";

	CRect   rect;
    GetClientRect(&rect);
	Ogre::RenderTarget *RenderWindow = Root->getRenderTarget("Walking");

	if (RenderWindow == NULL)
	{
	try
	{
		m_RenderWindow = Root->createRenderWindow("Walking", rect.Width(), rect.Height(), false, &parms);
	}
    catch(...)
	{
		MessageBox("Cannot initialize\nCheck that graphic-card driver is up-to-date", "Initialize Render System", MB_OK | MB_ICONSTOP);
		exit(EXIT_SUCCESS);
	}
	}
// Load resources
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    // Create the camera
    m_Camera = SceneManager->createCamera("Camera");
    m_Camera->setNearClipDistance(10);
	m_Camera->setFarClipDistance(10000); 
	m_Camera->setCastShadows(false);
	m_Camera->setUseRenderingDistance(true);

	Ogre::SceneNode *CameraNode = NULL;
	CameraNode = SceneManager->getRootSceneNode()->createChildSceneNode("CameraNode");

	Ogre::Viewport* Viewport = NULL;
	
	if (0 == m_RenderWindow->getNumViewports())
	{
		Viewport = m_RenderWindow->addViewport(m_Camera);
		Viewport->setBackgroundColour(Ogre::ColourValue(0.8f, 0.8f, 0.8f));
	}

    // Alter the camera aspect ratio to match the viewport
    m_Camera->setAspectRatio(Ogre::Real(rect.Width()) / Ogre::Real(rect.Height()));

	Ogre::SceneNode *TopographyNode = SceneManager->getRootSceneNode()->createChildSceneNode("Topography");
	Ogre::Entity *TopographyEntity = SceneManager->createEntity("Topography", "Topography.mesh");
	TopographyNode->attachObject(TopographyEntity);
	
	Ogre::AxisAlignedBox TopographyBox = TopographyEntity->getBoundingBox();
	
	Ogre::Vector3 Minimum = TopographyBox.getMinimum();
	Ogre::Vector3 Center = TopographyBox.getCenter();

	Ogre::SceneNode *RobotNode = SceneManager->getRootSceneNode()->createChildSceneNode("Robot");
	Ogre::Entity *RobotEntity = SceneManager->createEntity("Robot", "robot.mesh");
	RobotNode->attachObject(RobotEntity);
	RobotEntity->getParentNode()->scale(10,10,10);
	Ogre::AxisAlignedBox RobotBox = RobotEntity->getBoundingBox();

	RobotNode->setPosition(Ogre::Vector3(Minimum[0], Minimum[1] + RobotBox.getSize()[1], Minimum[2]));

	m_Camera->setPosition(Ogre::Vector3(Minimum[0], Minimum[1] + 5000, Minimum[2]));
	m_Camera->lookAt(Center);
	
	m_Camera->setPolygonMode(Ogre::PolygonMode::PM_WIREFRAME);

	m_Animation = RobotEntity->getAnimationState("Walk");
	m_Animation->setEnabled(true);
	
	m_CollisionTools = new MOC::CollisionTools(SceneManager);

	Root->renderOneFrame();
}
TileSelection OgreDetourTileCache::getTileSelection(const Ogre::AxisAlignedBox &selectionArea)
{
// TODO Account for origin? Have a look at dtTileCache::queryTiles()
    TileSelection result;

    // Verify whether area to select falls within tilecache bounds, otherwise clip
    Ogre::Vector3 min = selectionArea.getMinimum();
    if (min.x < m_cfg.bmin[0])
        min.x = m_cfg.bmin[0];
    if (min.z < m_cfg.bmin[2])
        min.z = m_cfg.bmin[2];
    if (min.x > m_cfg.bmax[0])
        min.x = m_cfg.bmax[0];
    if (min.z > m_cfg.bmax[2])
        min.z = m_cfg.bmax[2];

    Ogre::Vector3 max = selectionArea.getMaximum();
    if (max.x < m_cfg.bmin[0])
        max.x = m_cfg.bmin[0];
    if (max.z < m_cfg.bmin[2])
        max.z = m_cfg.bmin[2];
    if (max.x > m_cfg.bmax[0])
        max.x = m_cfg.bmax[0];
    if (max.z > m_cfg.bmax[2])
        max.z = m_cfg.bmax[2];


    // Width of one tile in world units
    float tileWidth = getTileSize();

    // Calculate tile index range that falls within bounding box
    result.minTx = (min.x - m_cfg.bmin[0]) / tileWidth;
    result.maxTx = (max.x - m_cfg.bmin[0]) / tileWidth;
    result.minTy = (min.z - m_cfg.bmin[2]) / tileWidth;
    result.maxTy = (max.z - m_cfg.bmin[2]) / tileWidth;
        // TODO you can also go the other route: using cellsize and tilesize

// Let's assume these will be correct for a small performance gain
/*
    // Assert tx and ty are within index bounds, otherwise clip
    if (result.minTx < 0)
        result.minTx = 0;
    if (result.maxTx < 0)
        result.maxTx = 0;
    if (result.minTx > m_tw)
        result.minTx = m_tw;
    if (result.maxTx > m_tw)
        result.maxTx = m_tw;

    if (result.minTy < 0)
        result.minTy = 0;
    if (result.maxTy < 0)
        result.maxTy = 0;
    if (result.minTy > m_th)
        result.minTy = m_th;
    if (result.maxTy > m_th)
        result.maxTy = m_th;
*/

    // Calculate proper bounds aligned to tile bounds
    min.x = m_cfg.bmin[0] + (result.minTx * tileWidth);
    min.y = m_cfg.bmin[1];
    min.z = m_cfg.bmin[2] + (result.minTy * tileWidth);

    max.x = m_cfg.bmin[0] + ((result.maxTx+1) * tileWidth);
    max.y = m_cfg.bmax[1];
    max.z = m_cfg.bmin[2] + ((result.maxTy+1) * tileWidth);
// TODO does this box need to be offset a little further with borders?


    // Return result
    result.bounds.setMinimum(min);
    result.bounds.setMaximum(max);

    return result;
}
Beispiel #20
0
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
{
    Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
    assert(insert);

    NifOgre::NIFLoader::load(mesh);
    Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);


    Ogre::Vector3 extents = ent->getBoundingBox().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", "Objects");

    // 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;

    Ogre::AxisAlignedBox bounds = ent->getBoundingBox();
    bounds = Ogre::AxisAlignedBox(
        insert->_getDerivedPosition() + bounds.getMinimum(),
        insert->_getDerivedPosition() + bounds.getMaximum()
    );

    bounds.scale(insert->getScale());
    mBounds[ptr.getCell()].merge(bounds);

    bool transparent = false;
    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)
    {
        insert->attachObject(ent);

        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->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());

        sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics);

        sg->setCastShadows(true);

        sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);

        mRenderer.getScene()->destroyEntity(ent);
    }
}