コード例 #1
0
bool SystemWindowManager::CheckWindowCollision(bool canChangeSelection, Vector2 *outRelativePosition)
{
    Vector3 origin = m_Controller->mRotationNode->convertLocalToWorldPosition(Vector3::ZERO);
    Vector3 cursor = m_MosueCursor->GetPosition();
    //convert to a vector 3 going into the screen
    Vector3 other = cursor - origin;

    Vector3 result;
    Entity* entity = NULL;
    float distToColl = -1.0f;
    m_MosueCursor->SetVisible(false);
    m_CollisionTools.raycastFromPoint(origin, other, result, entity, distToColl);
    m_MosueCursor->SetVisible(true);

    if(entity)
    {
        AxisAlignedBox bounds = entity->getBoundingBox();
        SceneNode *node = entity->getParentSceneNode();
        Vector3 nodePosition =  node->getPosition();
        Vector3 nodeWorldPosition =  node->convertLocalToWorldPosition(Vector3::ZERO);
        Vector3 position = node->convertWorldToLocalPosition(result);
        double relx, rely = 0;

        Vector3 topLeft = bounds.getCorner(AxisAlignedBox::FAR_LEFT_TOP);
        Vector3 bottomRight = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM);

        relx = (position.x - topLeft.x) / (bottomRight.x - topLeft.x);
        rely = (position.y - topLeft.y) / (bottomRight.y - topLeft.y);


        if(m_SelectedWindow->GetMaterialName() == entity->getName())
        {
            //todo figure out the mouse coordiantes
            m_SelectedWindow->CheckActiveWindow(relx, rely);
            *outRelativePosition = Vector2(relx, rely);
            return true;
        }
        else if(canChangeSelection)
        {
            for (std::vector<SystemWindow*>::iterator it = m_Windows.begin(); it != m_Windows.end(); ++it)
            {
                if((*it)->GetMaterialName() == entity->getName())
                {
                    //todo deactivate the old window here
                    m_SelectedWindow = (*it);
                    m_SelectedWindow->CheckActiveWindow(relx, rely);
                    *outRelativePosition = Vector2(relx, rely);
                    return true;
                }
            }
        }
        return false;
    }
    else if(canChangeSelection)
    {
        RemoveHighlightedThumbnail();
    }

    return false;
}
コード例 #2
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;
    }