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