Jump to content
Sign in to follow this  
Дракан

Наведение курсора на модель

Recommended Posts

Добрый вечер форумчане!

 

Нужна помощь, помню как то решал ее, но забыл.

 

При наведении курсора на аппарель не появляется значок атаки персонажа. Если память не изменяет это связано с моделями.

https://skr.sh/sAmFBoBCzJN

 

Другая аппарель при том же наведении

https://skr.sh/sAmBirG9rFU

Share this post


Link to post
Share on other sites

Привет, @Дракан! Попробуй сравнить строки этих аппарелей в ItemInfo.txt, возможно, там есть какие-то различия, влияющие на поведение курсора.

 

@e1mer по существу вопроса советы будут?

  • Like 1

Share this post


Link to post
Share on other sites
22 часа назад, V3ct0r сказал:

Привет, @Дракан! Попробуй сравнить строки этих аппарелей в ItemInfo.txt, возможно, там есть какие-то различия, влияющие на поведение курсора.

 

@e1mer по существу вопроса советы будут?

Нет конечно))

  • Like 1

Share this post


Link to post
Share on other sites

@Дракан, привет!

 

Есть какие-нибудь результаты по решению проблемы?


Share this post


Link to post
Share on other sites
В 30.10.2021 в 21:16, Дракан сказал:

Добрый вечер форумчане!

 

Нужна помощь, помню как то решал ее, но забыл.

 

При наведении курсора на аппарель не появляется значок атаки персонажа. Если память не изменяет это связано с моделями.

https://skr.sh/sAmFBoBCzJN

 

Другая аппарель при том же наведении

https://skr.sh/sAmBirG9rFU

Проблема именно с моделями, копай в этом направлении. ItemInfo тут не причем. 

  • Thanks 1

Share this post


Link to post
Share on other sites

Судя по коду, проблема связана с матрицами самой модели (часть тела).

 

Есть функция CWorldScene::CursorFrame, она вызывается раз в фрейм (30 раз в секунду) и отвечает за определение действия при наведении на цель.

 

Вырезка из собственных исходников с комментариями:

        CCharacter* pCha = HitSelectCharacter(nMouseX, nMouseY, enumSC_ALL); // Ищет актера в позициях мышки (любого)

        if (pCha)
        {
            if (GetMainCha() != pCha)
            {
                CSkillRecord* pSkill = GetMainCha()->GetDefaultSkillInfo();
                // Если используется дефолтный скилл (бить рукой)

                if (pCha->getEvent())
                {
                    // с целью можно взаимодействовать

                    CancelHoverFrame();

                    if (_HaveEventCursor(pCha->getEvent(), GetMainCha()->GetMainType()))
                    {
                        // у цели есть свой курсор

                        _cMouseDown.SetEvent(pCha, pCha->getEvent());
                    }
                    else
                    {
                        CCursor::I()->SetFrame(CCursor::stStop);
                    }

                    return;
                }
                if (pCha->IsNPC())
                {
                    // Если выбранная цель NPC

                    CancelHoverFrame();

                    CCursor::I()->SetFrame(CCursor::stChat);

                    pCha->SetColor(_bAttackRed, _bAttackGreen, _bAttackBlue);

                    _cMouseDown.SetNpc(pCha);

                    return;
                }
                if (pSkill && g_SkillUse.IsAttack(pSkill, GetMainCha(), pCha) || g_pGameApp->IsCtrlPress())
                {
                    // Цель можно атаковать или зажат CTRL

                    if (pCha->IsMonster() && !g_pGameApp->IsCtrlPress() || !pCha->IsMonster())
                    {
                        // Если это монстр, то только если CTRL не зажат

                        HoverFrame(pCha);

                        CCursor::I()->SetFrame(CCursor::stAttack);

                        pCha->SetColor(_bAttackRed, _bAttackGreen, _bAttackBlue);

                        _cMouseDown.SetAttackCha(pSkill, pCha, CGameApp::GetCurTick());

                        return;
                    }
                }
                if (pCha->IsPlayer())
                {
                    // Если выбранная цель игрок

                    HoverFrame(pCha);

                    CCursor::I()->SetFrame(CCursor::stMouse);
                    pCha->SetColor(_bAttackRed, _bAttackGreen, _bAttackBlue);

                    if (g_pGameApp->IsAltPress())
                    {
                        CCursor::I()->SetFrame(CCursor::stActive);

                        _cMouseDown.SetFollow(pCha);
                    }

                    return;
                }
            }
            return;
        }

 

Тут нас интересует

CCharacter* pCha = HitSelectCharacter(nMouseX, nMouseY, enumSC_ALL); // Ищет актера в позициях мышки (любого)

 

Внутри которой идёт поиск цели в указанных координатах nMouseX и MouseY и срабатывает метод

LW_RESULT MPCharacter::HitTestPrimitive(lwPickInfo* info, const lwVector3* org, const lwVector3* ray)
{
	return _physique->HitTestPrimitive(info, org, ray);
}

А сам метод _physique->HitTestPrimitive пробегает по максимальному количеству примитив у модели и смотрит вхождение в каждую.

 

lwPhysique::HitTestPrimitive(lwPickInfo* info, const lwVector3* org, const lwVector3* ray)

LW_MAX_SUBSKIN_NUM равен 10

	for (DWORD i = 0; i < LW_MAX_SUBSKIN_NUM; i++)
	{
		if ((imp_generic = _obj_seq[i]) == 0)
			continue;

		if (LW_SUCCEEDED(imp_generic->HitTest(&x, org, ray)))
		{
			if ((obj_id == LW_INVALID_INDEX) || (xx.dis > x.dis))
			{
				xx = x;
				obj_id = i;
			}
		}
	}

 

Исходя из этого можно сделать вывод, что проблема в том что imp_generic->HitTest возвращает отрицательный результат => не может найти вхождение nMouseX и nMouseY (относительно модели персонажа) в матрицу модели (часть тела).

LW_RESULT lwPrimitive::HitTest(lwPickInfo* info, const lwVector3* org, const lwVector3* ray)
{
	LW_RESULT ret = LW_RET_FAILED;

	if (_helper_object == 0)
		goto __ret;

	lwIBoundingSphere* bs = 0;
	lwIBoundingBox* bb = 0;

	lwMatrix44* mat = _render_agent->GetGlobalMatrix();

	if ((bs = _helper_object->GetBoundingSphere()) != 0)
	{
		if (LW_SUCCEEDED(bs->HitTest(info, org, ray, mat)))
			goto __addr_ret_ok;
	}

	if ((bb = _helper_object->GetBoundingBox()) != 0)
	{
		if (LW_SUCCEEDED(bb->HitTest(info, org, ray, mat)))
			goto __addr_ret_ok;
	}

	goto __ret;

__addr_ret_ok:

	ret = LW_RET_OK;

__ret:

	return ret;
}

 

Вероятнее всего проблема связана с тем что модель экспортировали не той версией, которую использует игра (разная структуру) исправить это можно если только переделать модель или пере экспортировать.

Edited by Kst
  • Like 2
  • Thanks 1

Работаем над портированием пиратии под все платформы (win, linux, android, macos, ios)

We are developing the tales of pirates to all platform (win, linux, android, macos, ios)

 

telegram: https://t.me/magicsea_online

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...