コード例 #1
0
	void RenderBoxScene::updateViewport()
	{
		if (mCanvas->getWidth() <= 1 || mCanvas->getHeight() <= 1)
			return;

		if (mEntity != nullptr && mCamera != nullptr)
		{
			mCamera->setAspectRatio((float)mCanvas->getWidth() / (float)mCanvas->getHeight());

			AxisAlignedBox box;
			const Vector3& dpos = mEntity->getParentSceneNode()->_getDerivedPosition();
			box.merge(mEntity->getBoundingBox().getMinimum() + dpos);
			box.merge(mEntity->getBoundingBox().getMaximum() + dpos);
			if (box.isNull()) return;

			Vector3 vec = box.getSize();
			float width = sqrt(vec.x * vec.x + vec.z * vec.z), height = vec.y;
			float len2 = width / mCamera->getAspectRatio(), len1 = height;
			if (len1 < len2)  len1 = len2;
			len1 /= 0.86;  // [sqrt(3)/2] for 60 degrees field of view

			Vector3 pos = box.getCenter();
			pos.z += vec.z / 2 + len1 + 1/* min dist*/;
			pos += Vector3(0, height * 0.9f/* pitch*/, len1 * 0.1f);
			pos *= 0.85f;  //* closer
			Vector3 look = Vector3(0, box.getCenter().y * 0.8f, 0);

			mCameraNode->setPosition(pos);
			mCameraNode->lookAt(look, Node::TS_WORLD);
		}
	}
コード例 #2
0
ファイル: OgreOctreeCamera.cpp プロジェクト: Kanma/Ogre
OctreeCamera::Visibility OctreeCamera::getVisibility( const AxisAlignedBox &bound )
{

    // Null boxes always invisible
    if ( bound.isNull() )
        return NONE;

    // Get centre of the box
    Vector3 centre = bound.getCenter();
    // Get the half-size of the box
    Vector3 halfSize = bound.getHalfSize();

    bool all_inside = true;

    for ( int plane = 0; plane < 6; ++plane )
    {

        // Skip far plane if infinite view frustum
        if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0)
            continue;

        // This updates frustum planes and deals with cull frustum
        Plane::Side side = getFrustumPlane(plane).getSide(centre, halfSize);
        if(side == Plane::NEGATIVE_SIDE) return NONE;
        // We can't return now as the box could be later on the negative side of a plane.
        if(side == Plane::BOTH_SIDE)
                all_inside = false;
    }

    if ( all_inside )
        return FULL;
    else
        return PARTIAL;

}
コード例 #3
0
ファイル: Frustum.cpp プロジェクト: Nicussus/3dengine
//-----------------------------------------------------------------------
bool Frustum::IsVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy)
{
	// Null boxes always invisible
	if (bound.isNull()) return false;

	// Infinite boxes always visible
	if (bound.isInfinite()) return true;

	// Make any pending updates to the calculated frustum planes
	_UpdateFrustumPlanes();

	// Get centre of the box
	Vector3f centre = bound.getCenter();
	// Get the half-size of the box
	Vector3f halfSize = bound.getHalfSize();

	// For each plane, see if all points are on the negative side
	// If so, object is not visible
	for (int plane = 0; plane < 6; ++plane)
	{
		// Skip far plane if infinite view frustum
		if (plane == FRUSTUM_PLANE_FAR && m_farDist == 0)
			continue;

		Plane::Side side = m_frustumPlanes[plane].getSide(centre, halfSize);
		if (side == Plane::NEGATIVE_SIDE)
		{
			// ALL corners on negative side therefore out of view
			if (culledBy)
				*culledBy = (FrustumPlane)plane;
			return false;
		}
	}
	return true;
}
コード例 #4
0
	//-----------------------------------------------------------------------
	Plane::Side Plane::getSide (const AxisAlignedBox& box) const
	{
		if (box.isNull()) 
			return NO_SIDE;
		if (box.isInfinite())
			return BOTH_SIDE;

        return getSide(box.getCenter(), box.getHalfSize());
	}
コード例 #5
0
ファイル: OgreShadowCaster.cpp プロジェクト: yiliu1203/OGRE
    // ------------------------------------------------------------------------
    static bool isBoundOkForMcGuire(const AxisAlignedBox& lightCapBounds, const Ogre::Vector3& lightPosition)
    {
        // If light position is inside light cap bound then extrusion could be in opposite directions
        // and McGuire cap could intersect near clip plane of camera frustum without being noticed
        if(lightCapBounds.contains(lightPosition))
            return false;

        // If angular size of object is too high then extrusion could be in almost opposite directions,
        // interpolated points would be extruded by shorter distance, and strange geometry of McGuire cap
        // could be visible even for well tesselated meshes. As a heuristic we will avoid McGuire cap if
        // angular size is larger than 60 degrees - it guarantees that interpolated points would be
        // extruded by at least cos(60deg/2) ~ 86% of the original extrusion distance.
        if(lightCapBounds.getHalfSize().length() / (lightCapBounds.getCenter() - lightPosition).length() > 0.5) // if boundingSphereAngularSize > 60deg
        {
            // Calculate angular size one more time using edge corners angular distance comparision,
            // Determine lit sides of the bound, store in mask
            enum { L = 1, R = 2, B = 4, T = 8, F = 16, N = 32 }; // left, right, bottom, top, far, near
            unsigned lightSidesMask = 
                (lightPosition.x < lightCapBounds.getMinimum().x ? L : 0) | // left
                (lightPosition.x > lightCapBounds.getMaximum().x ? R : 0) | // right
                (lightPosition.y < lightCapBounds.getMinimum().y ? B : 0) | // bottom
                (lightPosition.y > lightCapBounds.getMaximum().y ? T : 0) | // top
                (lightPosition.z < lightCapBounds.getMinimum().z ? F : 0) | // far
                (lightPosition.z > lightCapBounds.getMaximum().z ? N : 0);  // near
            
            // find corners on lit/unlit edge (should not be more than 6 simultaneously, but better be safe than sorry)
            Ogre::Vector3 edgeCorners[8]; 
            unsigned edgeCornersCount = 0;
            std::pair<unsigned, AxisAlignedBox::CornerEnum> cornerMap[8] = {
                { F|L|B, AxisAlignedBox::FAR_LEFT_BOTTOM }, { F|R|B, AxisAlignedBox::FAR_RIGHT_BOTTOM },
                { F|L|T, AxisAlignedBox::FAR_LEFT_TOP },    { F|R|T, AxisAlignedBox::FAR_RIGHT_TOP },
                { N|L|B, AxisAlignedBox::NEAR_LEFT_BOTTOM },{ N|R|B, AxisAlignedBox::NEAR_RIGHT_BOTTOM },
                { N|L|T, AxisAlignedBox::NEAR_LEFT_TOP },   { N|R|T, AxisAlignedBox::NEAR_RIGHT_TOP }};
            for(auto& c : cornerMap)
                if((lightSidesMask & c.first) != 0 && (lightSidesMask & c.first) != c.first) // if adjacent sides not all lit or all unlit
                    edgeCorners[edgeCornersCount++] = lightCapBounds.getCorner(c.second);
            
            // find max angular size in range [0..pi] by finding min cos of angular size, range [1..-1]
            Real cosAngle = 1.0;
            for(unsigned i0 = 0; i0 + 1 < edgeCornersCount; ++i0)
                for(unsigned i1 = i0 + 1; i1 < edgeCornersCount; ++i1)
                {
                    // 4~6 edge corners, 6~15 angular distance calculations
                    Vector3 a = (edgeCorners[i0] - lightPosition).normalisedCopy();
                    Vector3 b = (edgeCorners[i1] - lightPosition).normalisedCopy();
                    Real cosAB = a.dotProduct(b);
                    if(cosAngle > cosAB)
                        cosAngle  = cosAB;
                }
            
            if(cosAngle < 0.5) // angularSize > 60 degrees
                return false;
        }

        return true;
    }
コード例 #6
0
	/* A 'more detailed' check for visibility of an AAB.  This function returns
	  none, partial, or full for visibility of the box.  This is useful for 
	  stuff like Octree leaf culling */
	PCZFrustum::Visibility PCZFrustum::getVisibility( const AxisAlignedBox &bound )
	{

		// Null boxes always invisible
		if ( bound.isNull() )
			return NONE;

		// Get centre of the box
		Vector3 centre = bound.getCenter();
		// Get the half-size of the box
		Vector3 halfSize = bound.getHalfSize();

		bool all_inside = true;

        // Check originplane if told to
        if (mUseOriginPlane)
        {
            Plane::Side side = mOriginPlane.getSide(centre, halfSize);
            if (side == Plane::NEGATIVE_SIDE)
            {
				return NONE;
            }
			// We can't return now as the box could be later on the negative side of another plane.
			if(side == Plane::BOTH_SIDE) 
            {
                all_inside = false;
            }
        }

        // For each active culling plane, see if the entire aabb is on the negative side
        // If so, object is not visible
        PCPlaneList::iterator pit = mActiveCullingPlanes.begin();
        while ( pit != mActiveCullingPlanes.end() )
        {
            PCPlane * plane = *pit;
            Plane::Side xside = plane->getSide(centre, halfSize);
			if(xside == Plane::NEGATIVE_SIDE) 
            {
                return NONE;
            }
			// We can't return now as the box could be later on the negative side of a plane.
			if(xside == Plane::BOTH_SIDE) 
            {
                all_inside = false;
				break;
            }
            pit++;
        }

		if ( all_inside )
			return FULL;
		else
			return PARTIAL;

	}
コード例 #7
0
static Sphere aabbToSphere(const AxisAlignedBox& aabb)
{
	if (!aabb.isNull())
	{
		// Compute sphere
		float radius = -1.0f;
		const Vector3* corners = aabb.getAllCorners();
		for(unsigned int i = 0; i < 6; ++i)
		{
			float distance = corners[i].distance(aabb.getCenter());
			if (distance>radius)
			{
				radius = distance;
			}
		}
		return Sphere(aabb.getCenter(), radius);
	}
    else
	    return Sphere(Vector3::ZERO, -1.0f);
}
コード例 #8
0
	virtual bool processUnbufferedKeyInput(const FrameEvent& evt) {
		if(mKeyboard->isKeyDown(OIS::KC_V))
		{
			_sceneRoot->_update(true, true);
			_sceneRoot->_updateBounds();
			std::cout << "Frame camera" << std::endl;
			AxisAlignedBox box = _sceneRoot->_getWorldAABB();
			std::cout << "Center: " << box.getCenter() << std::endl;
		}
		return ExampleFrameListener::processUnbufferedKeyInput(evt);
	}
コード例 #9
0
void DebugDraw::draw(const AxisAlignedBox& axisAlignedBox, const Color& color) const
{
	if (!LineGeometryManager::getInstance()->getLineGeometry("Square").get())
	{
		return;
	}

	Matrix4x4 modelMatrix;

	// Front
	modelMatrix.identity();
	modelMatrix.translate(axisAlignedBox.getCenter().getX(), axisAlignedBox.getCenter().getY(), axisAlignedBox.getCenter().getZ());
	modelMatrix.translate(0.0f, 0.0f, axisAlignedBox.getHalfDepth());
	modelMatrix.rotateRzRyRx(0.0f, 0.0f, 0.0f);
	modelMatrix.scale(axisAlignedBox.getHalfWidth(), axisAlignedBox.getHalfHeight(), 0.0f);
	LineGeometryManager::getInstance()->getLineGeometry("Square")->draw(modelMatrix, color);

	// Back
	modelMatrix.identity();
	modelMatrix.translate(axisAlignedBox.getCenter().getX(), axisAlignedBox.getCenter().getY(), axisAlignedBox.getCenter().getZ());
	modelMatrix.translate(0.0f, 0.0f, -axisAlignedBox.getHalfDepth());
	modelMatrix.rotateRzRyRx(0.0f, 0.0f, 0.0f);
	modelMatrix.scale(axisAlignedBox.getHalfWidth(), axisAlignedBox.getHalfHeight(), 0.0f);
	LineGeometryManager::getInstance()->getLineGeometry("Square")->draw(modelMatrix, color);

	// Top
	modelMatrix.identity();
	modelMatrix.translate(axisAlignedBox.getCenter().getX(), axisAlignedBox.getCenter().getY(), axisAlignedBox.getCenter().getZ());
	modelMatrix.translate(0.0f, axisAlignedBox.getHalfHeight(), 0.0f);
	modelMatrix.rotateRzRyRx(0.0f, 0.0f, 90.0f);
	modelMatrix.scale(axisAlignedBox.getHalfWidth(), axisAlignedBox.getHalfDepth(), 0.0f);
	LineGeometryManager::getInstance()->getLineGeometry("Square")->draw(modelMatrix, color);

	// Bottom
	modelMatrix.identity();
	modelMatrix.translate(axisAlignedBox.getCenter().getX(), axisAlignedBox.getCenter().getY(), axisAlignedBox.getCenter().getZ());
	modelMatrix.translate(0.0f, -axisAlignedBox.getHalfHeight(), 0.0f);
	modelMatrix.rotateRzRyRx(0.0f, 0.0f, 90.0f);
	modelMatrix.scale(axisAlignedBox.getHalfWidth(), axisAlignedBox.getHalfDepth(), 0.0f);
	LineGeometryManager::getInstance()->getLineGeometry("Square")->draw(modelMatrix, color);

	// Left and Right not needed
}
コード例 #10
0
void SurveyMapManager::init()
{
    AxisAlignedBox aab   = App::GetSimTerrain()->getTerrainCollisionAAB();
    Vector3 terrain_size = App::GetSimTerrain()->getMaxTerrainSize();
    bool use_aab         = App::GetSimTerrain()->isFlat() && std::min(aab.getSize().x, aab.getSize().z) > 50.0f;

    if (terrain_size.isZeroLength() || use_aab && (aab.getSize().length() < terrain_size.length()))
    {
        terrain_size = aab.getSize();
        terrain_size.y = aab.getMaximum().y;
        Vector3 offset = aab.getCenter() - terrain_size / 2;
        mMapCenterOffset = Vector2(offset.x, offset.z);
    }

    mTerrainSize = Vector2(terrain_size.x, terrain_size.z);
    mPlayerPosition = mTerrainSize / 2;
    mMapCenter = mTerrainSize / 2;
    mMapSize = mTerrainSize;

    ConfigOptionMap ropts = App::GetOgreSubsystem()->GetOgreRoot()->getRenderSystem()->getConfigOptions();
    int resolution = StringConverter::parseInt(StringUtil::split(ropts["Video Mode"].currentValue, " x ")[0], 1024);
    int fsaa = StringConverter::parseInt(ropts["FSAA"].currentValue, 0);
    int res = std::pow(2, std::floor(std::log2(resolution)));

    mMapTextureCreatorStatic = std::unique_ptr<SurveyMapTextureCreator>(new SurveyMapTextureCreator(terrain_size.y));
    mMapTextureCreatorStatic->init(res, fsaa);
    mMapTextureCreatorStatic->update(mMapCenter + mMapCenterOffset, mMapSize);

    // TODO: Find out how to zoom into the static texture instead
    mMapTextureCreatorDynamic = std::unique_ptr<SurveyMapTextureCreator>(new SurveyMapTextureCreator(terrain_size.y));
    mMapTextureCreatorDynamic->init(res / 4, fsaa);
    mMapTextureCreatorDynamic->update(mMapCenter + mMapCenterOffset, mMapSize);

    mMapTexture->eventMouseSetFocus      += MyGUI::newDelegate(this, &SurveyMapManager::setFocus);
    mMapTexture->eventMouseLostFocus     += MyGUI::newDelegate(this, &SurveyMapManager::lostFocus);
    mMapTexture->eventMouseMove          += MyGUI::newDelegate(this, &SurveyMapManager::mouseMove);
    mMapTexture->eventMouseButtonPressed += MyGUI::newDelegate(this, &SurveyMapManager::mousePressed);

    mCursorEntity = createMapEntity("other");
    mCursorEntity->setVisibility(false);
    mCursorEntity->setCaption(_L("Teleport"));
}
コード例 #11
0
ファイル: Actor.cpp プロジェクト: windrobin/ogremeshviewer
Actor::Actor(const Ogre::String& name)
{
	_strName	= name;
	_AnimSpeed	= 1.0;
	_pCurAnim	= 0;
	_bPaused	= false;

	_bShowAxes			= false;
	_bShowBone			= false;
	_bShowBoundingBox	= false;

	_axesBoneTagPoint		= 0;

	//the body
	_pBodyEntity	= OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity(_strName, _strName);
	_pBodySceneNode	= OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode(_strName);
	_pBodySceneNode->attachObject(_pBodyEntity);

	//the body axes
	String axesName = _strName + "_" + "axes";
	_axesEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity(axesName, "axes.mesh");
	SceneNode* pAxesNode = _pBodySceneNode->createChildSceneNode(axesName);
	pAxesNode->attachObject(_axesEntity);
	_axesEntity->setVisible(_bShowAxes);

	//the bone axes
	axesName = _strName + "_Bone_" + "axes";
	_axesBoneEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity(axesName, "axes.mesh");

	AxisAlignedBox aabb = _pBodyEntity->getBoundingBox();
	_vInitCenter = aabb.getCenter();
	_fVolumeSize = aabb.getSize().length();

	_scaleAxes = _fVolumeSize * 0.01;		//for Axes mesh size is about 13, i want the axes to be 1/10 of the mesh
	pAxesNode->setScale(_scaleAxes, _scaleAxes, _scaleAxes);

	AddBoneVisualizer();

	OgreFramework::getSingletonPtr()->AddActor(this);
}
コード例 #12
0
    bool PCZFrustum::isVisible( const AxisAlignedBox & bound) const
    {
        // Null boxes are always invisible
        if (bound.isNull()) return false;

        // Infinite boxes are always visible
        if (bound.isInfinite()) return true;

		// Get centre of the box
        Vector3 centre = bound.getCenter();
        // Get the half-size of the box
        Vector3 halfSize = bound.getHalfSize();

        // Check originplane if told to
        if (mUseOriginPlane)
        {
            Plane::Side side = mOriginPlane.getSide(centre, halfSize);
            if (side == Plane::NEGATIVE_SIDE)
            {
				return false;
            }
        }

        // For each extra active culling plane, see if the entire aabb is on the negative side
        // If so, object is not visible
        PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin();
        while ( pit != mActiveCullingPlanes.end() )
        {
            PCPlane * plane = *pit;
            Plane::Side xside = plane->getSide(centre, halfSize);
            if (xside == Plane::NEGATIVE_SIDE)
            {
				return false;
            }
            pit++;
        }
		return true;
    }
コード例 #13
0
	//-----------------------------------------------------------------------
	bool Frustum::isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy) const
	{
		// AABB盒子是个空盒子,不可见
		if (bound.isNull()) return false;

		// AABB盒子无限大
		if (bound.isInfinite()) return true;

		// 进行必要的更新
		updateFrustumPlanes();

		// 获取AABB盒子的中心
		Vector3 centre = bound.getCenter();
		// 获取盒子半大小向量
		Vector3 halfSize = bound.getHalfSize();

		// 遍历视锥体的每个平面,对每个平面, 见如果所有的点都在反面
		// 如果这样,对象不可见
		for (int plane = 0; plane < 6; ++plane)
		{
			// 如果视锥体无限,跳过远裁平面
			if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0)
				continue;

			Plane::Side side = mFrustumPlanes[plane].getSide(centre, halfSize);
			if (side == Plane::NEGATIVE_SIDE)
			{
				// 所有的角都在反面,那么在视域之外
				if (culledBy)
					*culledBy = (FrustumPlane)plane;
				return false;
			}

		}

		return true;
	}
コード例 #14
0
/** Checks how the second box intersects with the first.
*/
Intersection intersect( const PlaneBoundedVolume &one, const AxisAlignedBox &two )
{
    OctreeSceneManager::intersect_call++;
    // Null box?
    if (two.isNull()) return OUTSIDE;
    // Infinite box?
    if (two.isInfinite()) return INTERSECT;

    // Get centre of the box
    Vector3 centre = two.getCenter();
    // Get the half-size of the box
    Vector3 halfSize = two.getHalfSize();

    // For each plane, see if all points are on the negative side
    // If so, object is not visible.
    // If one or more are, it's partial.
    // If all aren't, full
    bool all_inside = true;
    PlaneList::const_iterator i, iend;
    iend = one.planes.end();
    for (i = one.planes.begin(); i != iend; ++i)
    {
        const Plane& plane = *i;

        Plane::Side side = plane.getSide(centre, halfSize);
        if(side == one.outside)
                return OUTSIDE;
        if(side == Plane::BOTH_SIDE)
                all_inside = false; 
    }

    if ( all_inside )
        return INSIDE;
    else
        return INTERSECT;

}
コード例 #15
0
ファイル: bound.cpp プロジェクト: ejabx/katana
Bound::Bound( const AxisAlignedBox & aabb )
{
	m_center = aabb.getCenter();
	m_radius = aabb.getExtents().x * 0.5f;
}