예제 #1
0
// Returns true if other has a similar stroke width to this.
bool BLOBNBOX::MatchingStrokeWidth(const BLOBNBOX& other,
                                   double fractional_tolerance,
                                   double constant_tolerance) const {
  // The perimeter-based width is used as a backup in case there is
  // no information in the blob.
  double p_width = area_stroke_width();
  double n_p_width = other.area_stroke_width();
  float h_tolerance = horz_stroke_width_ * fractional_tolerance
                     + constant_tolerance;
  float v_tolerance = vert_stroke_width_ * fractional_tolerance
                     + constant_tolerance;
  double p_tolerance = p_width * fractional_tolerance
                     + constant_tolerance;
  bool h_zero = horz_stroke_width_ == 0.0f || other.horz_stroke_width_ == 0.0f;
  bool v_zero = vert_stroke_width_ == 0.0f || other.vert_stroke_width_ == 0.0f;
  bool h_ok = !h_zero && NearlyEqual(horz_stroke_width_,
                                     other.horz_stroke_width_, h_tolerance);
  bool v_ok = !v_zero && NearlyEqual(vert_stroke_width_,
                                     other.vert_stroke_width_, v_tolerance);
  bool p_ok = h_zero && v_zero && NearlyEqual(p_width, n_p_width, p_tolerance);
  // For a match, at least one of the horizontal and vertical widths
  // must match, and the other one must either match or be zero.
  // Only if both are zero will we look at the perimeter metric.
  return p_ok || ((v_ok || h_ok) && (h_ok || h_zero) && (v_ok || v_zero));
}
예제 #2
0
/**********************************************************************
 * make_rotated_tess_blob
 *
 * Make a single Tess style blob, applying the given rotation and
 * renormalizing.
 **********************************************************************/
TBLOB *make_rotated_tess_blob(const DENORM* denorm, PBLOB *blob,
                              BOOL8 flatten) {
  if (denorm != NULL && denorm->block() != NULL &&
      denorm->block()->classify_rotation().y() != 0.0) {
    TBOX box = blob->bounding_box();
    int src_width = box.width();
    int src_height = box.height();
    src_width = static_cast<int>(src_width / denorm->scale() + 0.5);
    src_height = static_cast<int>(src_height / denorm->scale() + 0.5);
    int x_middle = (box.left() + box.right()) / 2;
    int y_middle = (box.top() + box.bottom()) / 2;
    PBLOB* rotated_blob = PBLOB::deep_copy(blob);
    rotated_blob->move(FCOORD(-x_middle, -y_middle));
    rotated_blob->rotate(denorm->block()->classify_rotation());
    ICOORD median_size = denorm->block()->median_size();
    int tolerance = median_size.x() / 8;
    // TODO(dsl/rays) find a better normalization solution. In the mean time
    // make it work for CJK by normalizing for Cap height in the same way
    // as is applied in compute_block_xheight when the row is presumed to
    // be ALLCAPS, i.e. the x-height is the fixed fraction
    // blob height * textord_merge_x / (textord_merge_x + textord_merge_asc)
    if (NearlyEqual(src_width, static_cast<int>(median_size.x()), tolerance) &&
        NearlyEqual(src_height, static_cast<int>(median_size.y()), tolerance)) {
      float target_height = bln_x_height * (textord_merge_x + textord_merge_asc)
                          / textord_merge_x;
      rotated_blob->scale(target_height / box.width());
      rotated_blob->move(FCOORD(0.0f,
                                bln_baseline_offset -
                                  rotated_blob->bounding_box().bottom()));
    }
    TBLOB* result = make_tess_blob(rotated_blob, flatten);
    delete rotated_blob;
    return result;
  } else {
    return make_tess_blob(blob, flatten);
  }
}
예제 #3
0
static bool Quadable(EERIEPOLY * ep, EERIEPOLY * ep2, float tolerance) {

	long count=0;

	long ep_notcommon=-1;
	long ep2_notcommon=-1;

	if(ep2->type & POLY_QUAD)
		return false;

	if(ep->tex != ep2->tex)
		return false;

	long typ1=ep->type&(~POLY_QUAD);
	long typ2=ep2->type&(~POLY_QUAD);

	if(typ1!=typ2)
		return false;

	if((ep->type & POLY_TRANS) && ep->transval != ep2->transval)
		return false;

	ep->norm = CalcFaceNormal(ep->v);

	if(glm::abs(glm::dot(ep->norm, ep2->norm)) < 1.f - tolerance)
		return false;

	for (long i=0;i<3;i++)
	{
		long common=-1;
		long common2=-1;

		for (long j=0;j<3;j++)
		{
			if (   ( NearlyEqual(ep->v[i].p.x,ep2->v[j].p.x) )
				&& ( NearlyEqual(ep->v[i].p.y,ep2->v[j].p.y) )
				&& ( NearlyEqual(ep->v[i].p.z,ep2->v[j].p.z) )
				&& ( NearlyEqual(ep->v[i].uv.x,ep2->v[j].uv.x) )
				&& ( NearlyEqual(ep->v[i].uv.y,ep2->v[j].uv.y) )
				)
			{
				count++;
				common=j;
			}

			if (   ( NearlyEqual(ep->v[j].p.x,ep2->v[i].p.x) )
				&& ( NearlyEqual(ep->v[j].p.y,ep2->v[i].p.y) )
				&& ( NearlyEqual(ep->v[j].p.z,ep2->v[i].p.z) )
				&& ( NearlyEqual(ep->v[j].uv.x,ep2->v[i].uv.x) )
				&& ( NearlyEqual(ep->v[j].uv.y,ep2->v[i].uv.y) )
				)
			{
				common2=j;
			}
		}

		if (common2==-1) ep2_notcommon=i;

		if (common==-1) ep_notcommon=i;
	}

	if ((count>=2) && (ep_notcommon!=-1) && (ep2_notcommon!=-1))
	{
		ep2->type |= POLY_QUAD;

		switch (ep2_notcommon)
		{
			case 1:
				CopyVertices(ep2,3,0);
				CopyVertices(ep2,0,1);
				CopyVertices(ep2,1,2);
				CopyVertices(ep2,2,3);
			break;

			case 2:
				CopyVertices(ep2,3,0);
				CopyVertices(ep2,0,2);
				CopyVertices(ep2,2,1);
				CopyVertices(ep2,1,3);

			break;
		}

		CopyVertices(ep2,3,0);
		ep2->v[3].p = ep->v[ep_notcommon].p;
		ep2->tv[3].uv = ep2->v[3].uv = ep->v[ep_notcommon].uv;
		ep2->tv[3].color = ep2->v[3].color = Color::white.toRGB();
		ep2->tv[3].rhw = ep2->v[3].rhw = 1.f;

	ep2->center = (ep2->v[0].p + ep2->v[1].p + ep2->v[2].p + ep2->v[3].p) * 0.25f;
	ep2->max = glm::max(ep2->max, ep2->v[3].p);
	ep2->min = glm::min(ep2->min, ep2->v[3].p);

	ep2->norm2 = ep->norm;

	ep2->area += fdist((ep2->v[1].p + ep2->v[2].p) * .5f, ep2->v[3].p)
				 * fdist(ep2->v[3].p, ep2->v[1].p)*.5f; // should this be v[2] instead of v[3]?

		return true;
	}

	return false;
}
예제 #4
0
void CTaskbarNotifier::Show(LPCTSTR szCaption, int nMsgType, LPCTSTR pszLink, BOOL bAutoClose)
{
	if (nMsgType == TBN_NONOTIFY)
		return;
	UINT nScreenWidth;
	UINT nScreenHeight;
	UINT nEvents;
	UINT nBitmapSize;
	CRect rcTaskbar;
	CTaskbarNotifierHistory* messagePTR;

	m_strCaption = szCaption;
	m_nActiveMessageType = nMsgType;
	m_strLink = pszLink;

	if (m_bAutoClose) // sets it only if already true, else wait for user action
		m_bAutoClose = bAutoClose;

	if ((nMsgType != TBN_NULL) && (nMsgType != TBN_LOG) && (nMsgType != TBN_IMPORTANTEVENT))
	{
		//Add element into string list. Max 5 elements.
		if (m_MessageHistory.GetCount() == 5) {
			messagePTR = (CTaskbarNotifierHistory*)m_MessageHistory.RemoveHead();
			delete messagePTR;
			messagePTR = NULL;
		}
		messagePTR = new CTaskbarNotifierHistory;
		messagePTR->m_strMessage = m_strCaption;
		messagePTR->m_nMessageType = nMsgType;
		messagePTR->m_strLink = m_strLink;
		m_MessageHistory.AddTail(messagePTR);
	}

	nScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
	nScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
	HWND hWndTaskbar = ::FindWindow(_T("Shell_TrayWnd"), 0);
	::GetWindowRect(hWndTaskbar, &rcTaskbar);

	// Daniel Lohmann: Calculate taskbar position from its window rect. However, on XP  it may be that 
	// the taskbar is slightly larger or smaller than the screen size. Therefore we allow some tolerance here.
	if (NearlyEqual(rcTaskbar.left, 0, TASKBAR_X_TOLERANCE) && NearlyEqual(rcTaskbar.right, nScreenWidth, TASKBAR_X_TOLERANCE))
	{
		// Taskbar is on top or on bottom
		m_nTaskbarPlacement = NearlyEqual(rcTaskbar.top, 0, TASKBAR_Y_TOLERANCE) ? ABE_TOP : ABE_BOTTOM;
		nBitmapSize = m_nBitmapHeight;
	}
	else
	{
		// Taskbar is on left or on right
		m_nTaskbarPlacement = NearlyEqual(rcTaskbar.left, 0, TASKBAR_X_TOLERANCE) ? ABE_LEFT : ABE_RIGHT;
		nBitmapSize = m_nBitmapWidth;
	}

	// We calculate the pixel increment and the timer value for the showing animation
	if (m_dwTimeToShow > m_dwTimerPrecision)
	{
		nEvents = min((m_dwTimeToShow / m_dwTimerPrecision) / 2, nBitmapSize); //<<-- enkeyDEV(Ottavio84) -Reduced frames of a half-
		//ADDED by VC-fengwen on 2007/10/08 <begin> : nEvents 有可能是0,则会出现异常。
		if (0 == nEvents)
			nEvents = 1;
		//ADDED by VC-fengwen on 2007/10/08 <end> : nEvents 有可能是0,则会出现异常。
		m_dwShowEvents = m_dwTimeToShow / nEvents;
		m_nIncrementShow = nBitmapSize / nEvents;
	}
	else
	{
		m_dwShowEvents = m_dwTimerPrecision;
		m_nIncrementShow = nBitmapSize;
	}

	// We calculate the pixel increment and the timer value for the hiding animation
	if (m_dwTimeToHide > m_dwTimerPrecision)
	{
		nEvents = min((m_dwTimeToHide / m_dwTimerPrecision / 2), nBitmapSize); //<<-- enkeyDEV(Ottavio84) -Reduced frames of a half-
		//ADDED by VC-fengwen on 2007/10/08 <begin> : nEvents 有可能是0,则会出现异常。
		if (0 == nEvents)
			nEvents = 1;
		//ADDED by VC-fengwen on 2007/10/08 <end> : nEvents 有可能是0,则会出现异常。
		m_dwHideEvents = m_dwTimeToHide / nEvents;
		m_nIncrementHide = nBitmapSize / nEvents;
	}
	else
	{
		m_dwShowEvents = m_dwTimerPrecision;
		m_nIncrementHide = nBitmapSize;
	}

	// Compute init values for the animation
	switch (m_nAnimStatus)
	{
		case IDT_HIDDEN:
			if (m_nTaskbarPlacement == ABE_RIGHT)
			{
				m_nCurrentPosX = rcTaskbar.left;
				m_nCurrentPosY = rcTaskbar.bottom - m_nBitmapHeight;
				m_nCurrentWidth = 0;
				m_nCurrentHeight = m_nBitmapHeight;
			}
			else if (m_nTaskbarPlacement == ABE_LEFT)
			{
				m_nCurrentPosX = rcTaskbar.right;
				m_nCurrentPosY = rcTaskbar.bottom - m_nBitmapHeight;
				m_nCurrentWidth = 0;
				m_nCurrentHeight = m_nBitmapHeight;
			}
			else if (m_nTaskbarPlacement == ABE_TOP)
			{
				m_nCurrentPosX = rcTaskbar.right - m_nBitmapWidth;
				m_nCurrentPosY = rcTaskbar.bottom;
				m_nCurrentWidth = m_nBitmapWidth;
				m_nCurrentHeight = 0;
			}
			else
			{
				// Taskbar is on the bottom or Invisible
				m_nCurrentPosX = rcTaskbar.right - m_nBitmapWidth;
				m_nCurrentPosY = rcTaskbar.top;
				m_nCurrentWidth = m_nBitmapWidth;
				m_nCurrentHeight = 0;
			}
			ShowWindow(SW_SHOWNOACTIVATE);
			SetTimer(IDT_APPEARING, m_dwShowEvents, NULL);
			break;

		case IDT_APPEARING:
			RedrawWindow();
			break;

		case IDT_WAITING:
			RedrawWindow();
			KillTimer(IDT_WAITING);
			SetTimer(IDT_WAITING, m_dwTimeToStay, NULL);
			break;

		case IDT_DISAPPEARING:
			KillTimer(IDT_DISAPPEARING);
			SetTimer(IDT_WAITING, m_dwTimeToStay, NULL);
			if (m_nTaskbarPlacement == ABE_RIGHT)
			{
				m_nCurrentPosX = rcTaskbar.left - m_nBitmapWidth;
				m_nCurrentWidth = m_nBitmapWidth;
			}
			else if (m_nTaskbarPlacement == ABE_LEFT)
			{
				m_nCurrentPosX = rcTaskbar.right;
				m_nCurrentWidth = m_nBitmapWidth;
			}
			else if (m_nTaskbarPlacement == ABE_TOP)
			{
				m_nCurrentPosY = rcTaskbar.bottom;
				m_nCurrentHeight = m_nBitmapHeight;
			}
			else
			{
				m_nCurrentPosY = rcTaskbar.top - m_nBitmapHeight;
				m_nCurrentHeight = m_nBitmapHeight;
			}

			SetWindowPos(&wndTopMost, m_nCurrentPosX, m_nCurrentPosY, m_nCurrentWidth, m_nCurrentHeight, SWP_NOACTIVATE);
			RedrawWindow();
			break;
	}
}
예제 #5
0
CSkeleton::ESkeletonStates CSkeleton::Follow()
{

	if (NearlyEqual(GetCurrAnimation()->GetCurrTime(), 0.05f))
	{
		AudioSystemWwise::Get()->PostEvent(AK::EVENTS::PLAYERFOOTSTEP, *GetPosition());
	}
	if (NearlyEqual(GetCurrAnimation()->GetCurrTime(), 0.5f))
	{
		AudioSystemWwise::Get()->PostEvent(AK::EVENTS::PLAYERFOOTSTEP, *GetPosition());
	}

	if (m_bIsGrounded)
		SetWorldVelocity({ 0, m_f3Velocity.y, 0 });
	else
		SetWorldVelocity({ knockBackVelocity.x, m_f3Velocity.y, knockBackVelocity.z });

	// Get the current path
	vector<XMFLOAT3>& vPath = GetPath(); // path here from group

	// Get the current velocity
	//XMVECTOR currentVelocity; XMLoadFloat3(&m_f3vel);

	if (DistanceToPlayer() < 500.0f)
	{
		return MOVING_IN;
	}

	// Node that I'm on along the path
	int nCurrentNode = GetCurNodeOnPath();


	if (nCurrentNode < 0 || vPath.empty())
	{

		BuildPathToPlayer();
		vPath = GetPath();

		if (vPath.size() < 2)
		{
			return FOLLOW;
		}
	}

	nCurrentNode = GetCurNodeOnPath();

	// Get the current positions
	XMFLOAT3 curPos = *GetPosition();
	XMFLOAT3 targetPos = vPath[nCurrentNode];

	// Convert them for math
	XMVECTOR mathPos = XMLoadFloat3(&curPos);
	XMVECTOR mathTarget = XMLoadFloat3(&targetPos);

	// Find the vector between the two points
	XMVECTOR mathToVec = XMVectorSubtract(mathTarget, mathPos);

	//XMFLOAT3 toVec; XMStoreFloat3(&toVec, mathToVec);

	// Normalize the toVector to get the direction
	XMVECTOR mathVelocity = XMVector3Normalize(mathToVec);



	// Add the separation factor
	//	mathVelocity += GetParentGroup()->CalculateSeparation(this);

	mathVelocity *= MOVE_SPEED;

	XMFLOAT3 realVelocity; XMStoreFloat3(&realVelocity, mathVelocity);
	realVelocity.y = m_f3Velocity.y;

	// Get the distance to target - ANY XYZ HOLDS THE LENGTH
	XMVECTOR mathDistToTarget = XMVector3Length(mathToVec);
	XMFLOAT3 distToTarget; XMStoreFloat3(&distToTarget, mathDistToTarget);

	// Offset the current node

	float nNextNodeDistance = 300.0f;



	// If i reached the node, move on the next one
	if (distToTarget.x < nNextNodeDistance && nCurrentNode >= 0)
	{
		nCurrentNode--;

	}
	Steering().Seek(targetPos);

	if (m_bIsGrounded)
	{
		Steering().Update(false, m_fScale);

		SetWorldVelocity(realVelocity);
	}
	SetNodeOnPath(nCurrentNode);
	return FOLLOW;
}
예제 #6
0
CSkeleton::ESkeletonStates CSkeleton::Retreating()
{
	if (NearlyEqual(GetCurrAnimation()->GetCurrTime(), 0.05f))
		AudioSystemWwise::Get()->PostEvent(AK::EVENTS::PLAYERFOOTSTEP, *GetPosition());
	if (NearlyEqual(GetCurrAnimation()->GetCurrTime(), 0.5f))
		AudioSystemWwise::Get()->PostEvent(AK::EVENTS::PLAYERFOOTSTEP, *GetPosition());

	if (m_bIsGrounded)
		SetWorldVelocity({ 0, m_f3Velocity.y, 0 });
	else
		SetWorldVelocity({ knockBackVelocity.x, m_f3Velocity.y, knockBackVelocity.z });

	// Get the current path
	vector<XMFLOAT3>& vPath = GetPath(); // path here from group

	// Node that I'm on along the path
	int nCurrentNode = GetCurNodeOnPath();

	// Clamp CurNode to 0 and max
	if (nCurrentNode < 0)
		return DEATH;

	// If no path was generated, then return
	if (vPath.size() <= 0)
	{
		nCurrentNode = -1;
		return DEATH;
	}
	// Get the current positions
	XMFLOAT3 curPos = *GetPosition();
	XMFLOAT3 targetPos = vPath[nCurrentNode];

	// Convert them for math
	XMVECTOR mathPos = XMLoadFloat3(&curPos);
	XMVECTOR mathTarget = XMLoadFloat3(&targetPos);

	// Find the vector between the two points
	XMVECTOR mathToVec = XMVectorSubtract(mathTarget, mathPos);

	// Normalize the toVector to get the direction
	XMVECTOR mathVelocity = XMVector3Normalize(mathToVec);

	// Add the separation factor
	//mathVelocity += GetParentGroup()->CalculateSeparation(this);
	//mathVelocity += GetParentGroup()->CalculateAlignment();
	mathVelocity *= MOVE_SPEED;

	XMFLOAT3 realVelocity; XMStoreFloat3(&realVelocity, mathVelocity);
	realVelocity.y = m_f3Velocity.y;

	// Get the distance to target - ANY XYZ HOLDS THE LENGTH
	XMVECTOR mathDistToTarget = XMVector3Length(mathToVec);
	XMFLOAT3 distToTarget; XMStoreFloat3(&distToTarget, mathDistToTarget);

	float nNextNodeDistance = 125.0f;

	Steering().Seek(targetPos);
	// If i reached the node, move on the next one
	if (distToTarget.x < nNextNodeDistance && nCurrentNode >= 0)
		nCurrentNode--;

	if (m_bIsGrounded)
	{
		Steering().Update(false, m_fScale);
		SetWorldVelocity(realVelocity);
	}
	else
		SetWorldVelocity({ knockBackVelocity.x, m_f3Velocity.y, knockBackVelocity.z });

	SetNodeOnPath(nCurrentNode);

	return RETREAT;
}