Commit 39dfc555 authored by D-AIRY's avatar D-AIRY

entity ray selection

parent fcb1f446
...@@ -309,6 +309,11 @@ void CBaseAnimating::setPos(const float3 & pos) ...@@ -309,6 +309,11 @@ void CBaseAnimating::setPos(const float3 & pos)
if(m_pRigidBody) if(m_pRigidBody)
{ {
m_pRigidBody->getWorldTransform().setOrigin(F3_BTVEC(pos)); m_pRigidBody->getWorldTransform().setOrigin(F3_BTVEC(pos));
if(m_pMgr->isEditorMode())
{
SPhysics_GetDynWorld()->updateSingleAabb(m_pRigidBody);
}
} }
} }
...@@ -318,6 +323,11 @@ void CBaseAnimating::setOrient(const SMQuaternion & q) ...@@ -318,6 +323,11 @@ void CBaseAnimating::setOrient(const SMQuaternion & q)
if(m_pRigidBody) if(m_pRigidBody)
{ {
m_pRigidBody->getWorldTransform().setRotation(Q4_BTQUAT(q)); m_pRigidBody->getWorldTransform().setRotation(Q4_BTQUAT(q));
if(m_pMgr->isEditorMode())
{
SPhysics_GetDynWorld()->updateSingleAabb(m_pRigidBody);
}
} }
} }
...@@ -487,3 +497,12 @@ void CBaseAnimating::setSkin(int iSkin) ...@@ -487,3 +497,12 @@ void CBaseAnimating::setSkin(int iSkin)
m_iSkin = iSkin; m_iSkin = iSkin;
} }
void CBaseAnimating::_initEditorBoxes()
{
// do nothing
}
void CBaseAnimating::_releaseEditorBoxes()
{
// do nothing
}
...@@ -59,6 +59,8 @@ public: ...@@ -59,6 +59,8 @@ public:
COLLISION_GROUP getCollisionGroup(); COLLISION_GROUP getCollisionGroup();
protected: protected:
virtual void _initEditorBoxes();
virtual void _releaseEditorBoxes();
void inputPlayAnim(inputdata_t * pInputdata); void inputPlayAnim(inputdata_t * pInputdata);
void inputPlayAnimNext(inputdata_t * pInputdata); void inputPlayAnimNext(inputdata_t * pInputdata);
......
...@@ -92,6 +92,8 @@ CBaseEntity::CBaseEntity(CEntityManager * pWorld): ...@@ -92,6 +92,8 @@ CBaseEntity::CBaseEntity(CEntityManager * pWorld):
CBaseEntity::~CBaseEntity() CBaseEntity::~CBaseEntity()
{ {
_releaseEditorBoxes();
m_pMgr->unreg(m_iId); m_pMgr->unreg(m_iId);
proptable_t * pt = getPropTable(); proptable_t * pt = getPropTable();
...@@ -149,6 +151,12 @@ void CBaseEntity::getSphere(float3 * center, float * radius) ...@@ -149,6 +151,12 @@ void CBaseEntity::getSphere(float3 * center, float * radius)
void CBaseEntity::setPos(const float3 & pos) void CBaseEntity::setPos(const float3 & pos)
{ {
m_vPosition = pos; m_vPosition = pos;
if(m_pEditorRigidBody)
{
m_pEditorRigidBody->getWorldTransform().setOrigin(F3_BTVEC(m_vPosition));
SPhysics_GetDynWorld()->updateSingleAabb(m_pEditorRigidBody);
}
} }
float3 CBaseEntity::getPos() float3 CBaseEntity::getPos()
...@@ -860,3 +868,42 @@ void CBaseEntity::_cleanup() ...@@ -860,3 +868,42 @@ void CBaseEntity::_cleanup()
void CBaseEntity::onUse(CBaseEntity *pUser) void CBaseEntity::onUse(CBaseEntity *pUser)
{ {
} }
void CBaseEntity::_initEditorBoxes()
{
if(m_pEditorRigidBody)
{
return;
}
float3 vBoxHalfSize = m_vEditorBoxSize * 0.5f;
m_pEditorCollideShape = new btBoxShape(F3_BTVEC(vBoxHalfSize));
btDefaultMotionState * motionState = new btDefaultMotionState(btTransform(Q4_BTQUAT(SMQuaternion()), F3_BTVEC(m_vPosition)));
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(
0, // mass
motionState, // initial position
m_pEditorCollideShape, // collision shape of body
btVector3(0,0,0) // local inertia
);
m_pEditorRigidBody = new btRigidBody(rigidBodyCI);
m_pEditorRigidBody->getInvMass();
m_pEditorRigidBody->setUserPointer(this);
SPhysics_AddShapeEx(m_pEditorRigidBody, CG_DEFAULT, CG_BULLETFIRE);
}
void CBaseEntity::_releaseEditorBoxes()
{
if(m_pEditorRigidBody)
{
SPhysics_RemoveShape(m_pEditorRigidBody);
}
mem_delete(m_pEditorRigidBody);
mem_delete(m_pEditorCollideShape);
}
float3 CBaseEntity::getEditorBoxSize()
{
return(m_vEditorBoxSize);
}
...@@ -134,6 +134,9 @@ public: ...@@ -134,6 +134,9 @@ public:
//! Обновляет действие флагов в режиме редактора уровня //! Обновляет действие флагов в режиме редактора уровня
virtual void updateFlags(){} virtual void updateFlags(){}
virtual float3 getEditorBoxSize();
private: private:
void setClassName(const char * name); void setClassName(const char * name);
void setDefaults(); void setDefaults();
...@@ -145,6 +148,8 @@ private: ...@@ -145,6 +148,8 @@ private:
protected: protected:
virtual void _cleanup(); virtual void _cleanup();
virtual void _initEditorBoxes();
virtual void _releaseEditorBoxes();
CEntityManager * m_pMgr; CEntityManager * m_pMgr;
...@@ -209,6 +214,14 @@ protected: ...@@ -209,6 +214,14 @@ protected:
void takeHealth(float fVal, CBaseEntity *pAttacker, CBaseEntity *pInflictor=NULL); void takeHealth(float fVal, CBaseEntity *pAttacker, CBaseEntity *pInflictor=NULL);
bool m_bSynced; bool m_bSynced;
//! Для редактора
//@{
float3_t m_vEditorBoxSize = float3_t(0.16f, 0.16f, 0.16f);
btCollisionShape * m_pEditorCollideShape = NULL;
btRigidBody * m_pEditorRigidBody = NULL;
//@}
}; };
#pragma warning(pop) #pragma warning(pop)
......
...@@ -55,6 +55,10 @@ CBaseEntity * CEntityFactoryMap::create(const char * szName, CEntityManager * pW ...@@ -55,6 +55,10 @@ CBaseEntity * CEntityFactoryMap::create(const char * szName, CEntityManager * pW
{ {
pEnt->onPostLoad(); pEnt->onPostLoad();
} }
if(pWorld->isEditorMode())
{
pEnt->_initEditorBoxes();
}
return(pEnt); return(pEnt);
} }
return(NULL); return(NULL);
......
...@@ -807,4 +807,40 @@ void CEntityManager::sheduleDestroy(CBaseEntity *pEnt) ...@@ -807,4 +807,40 @@ void CEntityManager::sheduleDestroy(CBaseEntity *pEnt)
{ {
pEnt->setFlags(pEnt->getFlags() | EF_REMOVED); pEnt->setFlags(pEnt->getFlags() | EF_REMOVED);
m_vEntRemoveList.push_back(pEnt); m_vEntRemoveList.push_back(pEnt);
if(m_isEditorMode)
{
pEnt->_releaseEditorBoxes();
}
}
void CEntityManager::setEditorMode(bool isEditor)
{
if(m_isEditorMode == isEditor)
{
return;
}
m_isEditorMode = isEditor;
for(int i = 0, l = m_vEntList.size(); i < l; ++i)
{
CBaseEntity * pEnt = m_vEntList[i];
if(!pEnt)
{
continue;
}
if(isEditor)
{
pEnt->_initEditorBoxes();
}
else
{
pEnt->_releaseEditorBoxes();
}
}
}
bool CEntityManager::isEditorMode()
{
return(m_isEditorMode);
} }
...@@ -108,6 +108,9 @@ public: ...@@ -108,6 +108,9 @@ public:
void sheduleDestroy(CBaseEntity *pEnt); void sheduleDestroy(CBaseEntity *pEnt);
void setEditorMode(bool isEditor = true);
bool isEditorMode();
protected: protected:
ID reg(CBaseEntity * pEnt); ID reg(CBaseEntity * pEnt);
void unreg(ID ent); void unreg(ID ent);
...@@ -127,6 +130,8 @@ protected: ...@@ -127,6 +130,8 @@ protected:
//! @warning это нужно хранить в течение работы проги, т.к. таблицы дефолтов ссылаются напрямую на этот объект //! @warning это нужно хранить в течение работы проги, т.к. таблицы дефолтов ссылаются напрямую на этот объект
ISXConfig * m_pDefaultsConf; ISXConfig * m_pDefaultsConf;
ISXConfig * m_pDynClassConf; ISXConfig * m_pDynClassConf;
bool m_isEditorMode = false;
}; };
#endif #endif
...@@ -752,6 +752,10 @@ GameData::GameData(HWND hWnd, bool isGame): ...@@ -752,6 +752,10 @@ GameData::GameData(HWND hWnd, bool isGame):
m_pPlayer->setActiveTool(pTool); m_pPlayer->setActiveTool(pTool);
} }
else
{
m_pMgr->setEditorMode(true);
}
} }
GameData::~GameData() GameData::~GameData()
{ {
......
...@@ -266,6 +266,9 @@ SX_LIB_API void SGame_SetDebugText(const char *szText); ...@@ -266,6 +266,9 @@ SX_LIB_API void SGame_SetDebugText(const char *szText);
*/ */
SX_LIB_API ID SGame_EntClone(ID idSrc); SX_LIB_API ID SGame_EntClone(ID idSrc);
/*! Находит объект по пересечению с лучем, в режиме редактора так же находит точечные объекты, в режиме игры - нет
*/
SX_LIB_API ID SGame_EntGetByRay(const float3 &vStart, const float3 &vDir, float3 *pHitPos = NULL);
#endif #endif
......
...@@ -10,6 +10,7 @@ See the license in LICENSE ...@@ -10,6 +10,7 @@ See the license in LICENSE
#include "sxgame.h" #include "sxgame.h"
#include <core/sxcore.h> #include <core/sxcore.h>
#include <gcore/sxgcore.h> #include <gcore/sxgcore.h>
#include <BulletCollision/NarrowPhaseCollision/btRaycastCallback.h>
#include "EntityManager.h" #include "EntityManager.h"
...@@ -200,8 +201,8 @@ SX_LIB_API void SGame_EditorRender(ID id, ID id_sel_tex, const float3 *pvRenderP ...@@ -200,8 +201,8 @@ SX_LIB_API void SGame_EditorRender(ID id, ID id_sel_tex, const float3 *pvRenderP
{ {
SG_PRECOND(_VOID); SG_PRECOND(_VOID);
CBaseEntity* bEnt = SGame_EntGet(id); CBaseEntity* pEnt = SGame_EntGet(id);
if (!bEnt) if (!pEnt)
return; return;
SMMATRIX mView, mProj; SMMATRIX mView, mProj;
...@@ -211,9 +212,11 @@ SX_LIB_API void SGame_EditorRender(ID id, ID id_sel_tex, const float3 *pvRenderP ...@@ -211,9 +212,11 @@ SX_LIB_API void SGame_EditorRender(ID id, ID id_sel_tex, const float3 *pvRenderP
SGCore_GetDXDevice()->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&mView); SGCore_GetDXDevice()->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&mView);
SGCore_GetDXDevice()->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&mProj); SGCore_GetDXDevice()->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&mProj);
if(strcmp(bEnt->getClassName(), "path_corner") == 0) float3 vBoxSize = pEnt->getEditorBoxSize();
if(strcmp(pEnt->getClassName(), "path_corner") == 0)
{ {
CPathCorner * pStartPoint = (CPathCorner*)bEnt; CPathCorner * pStartPoint = (CPathCorner*)pEnt;
if (!pStartPoint) if (!pStartPoint)
return; return;
...@@ -230,7 +233,7 @@ SX_LIB_API void SGame_EditorRender(ID id, ID id_sel_tex, const float3 *pvRenderP ...@@ -230,7 +233,7 @@ SX_LIB_API void SGame_EditorRender(ID id, ID id_sel_tex, const float3 *pvRenderP
{ {
len += pCur->GetLength(); len += pCur->GetLength();
++count; ++count;
SGCore_GetDXDevice()->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&SMMatrixTranslation(pCur->getPos())); SGCore_GetDXDevice()->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&SMMatrixTranslation(SMMatrixScaling(vBoxSize) * pCur->getPos()));
if (id == pCur->getId()) if (id == pCur->getId())
SGCore_GetDXDevice()->SetTexture(0, SGCore_LoadTexGetTex(id_sel_tex)); SGCore_GetDXDevice()->SetTexture(0, SGCore_LoadTexGetTex(id_sel_tex));
...@@ -279,7 +282,7 @@ SX_LIB_API void SGame_EditorRender(ID id, ID id_sel_tex, const float3 *pvRenderP ...@@ -279,7 +282,7 @@ SX_LIB_API void SGame_EditorRender(ID id, ID id_sel_tex, const float3 *pvRenderP
SGCore_GetDXDevice()->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&mView); SGCore_GetDXDevice()->SetTransform(D3DTS_VIEW, (D3DMATRIX*)&mView);
SGCore_GetDXDevice()->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&mProj); SGCore_GetDXDevice()->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&mProj);
SGCore_GetDXDevice()->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&(bEnt->getOrient().GetMatrix() * SMMatrixTranslation(pvRenderPos ? *pvRenderPos : bEnt->getPos()))/*bEnt->getWorldTM()*/); SGCore_GetDXDevice()->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&(SMMatrixScaling(vBoxSize) * pEnt->getOrient().GetMatrix() * SMMatrixTranslation(pvRenderPos ? *pvRenderPos : pEnt->getPos()))/*bEnt->getWorldTM()*/);
SGCore_GetDXDevice()->SetTexture(0, SGCore_LoadTexGetTex(id_sel_tex)); SGCore_GetDXDevice()->SetTexture(0, SGCore_LoadTexGetTex(id_sel_tex));
g_pFigureBox->DrawSubset(0); g_pFigureBox->DrawSubset(0);
...@@ -408,7 +411,7 @@ SX_LIB_API void SGame_SetDebugText(const char *szText) ...@@ -408,7 +411,7 @@ SX_LIB_API void SGame_SetDebugText(const char *szText)
SX_LIB_API ID SGame_EntClone(ID idSrc) SX_LIB_API ID SGame_EntClone(ID idSrc)
{ {
SG_PRECOND(NULL); SG_PRECOND(-1);
CBaseEntity *pEnt = GameData::m_pMgr->cloneEntity(GameData::m_pMgr->getById(idSrc)); CBaseEntity *pEnt = GameData::m_pMgr->cloneEntity(GameData::m_pMgr->getById(idSrc));
if(!pEnt) if(!pEnt)
...@@ -418,3 +421,28 @@ SX_LIB_API ID SGame_EntClone(ID idSrc) ...@@ -418,3 +421,28 @@ SX_LIB_API ID SGame_EntClone(ID idSrc)
return(pEnt->getId()); return(pEnt->getId());
} }
SX_LIB_API ID SGame_EntGetByRay(const float3 &vStart, const float3 &vDir, float3 *pHitPos)
{
SG_PRECOND(-1);
float3 vEnd = vStart + vDir * 10000.0f;
btCollisionWorld::ClosestRayResultCallback cb(F3_BTVEC(vStart), F3_BTVEC(vEnd));
cb.m_collisionFilterGroup = CG_BULLETFIRE;
cb.m_collisionFilterMask = CG_ALL;
cb.m_flags |= btTriangleRaycastCallback::kF_FilterBackfaces;
SPhysics_GetDynWorld()->rayTest(F3_BTVEC(vStart), F3_BTVEC(vEnd), cb);
if(cb.hasHit())
{
CBaseEntity *pEnt = (CBaseEntity*)cb.m_collisionObject->getUserPointer();
if(pEnt)
{
if(pHitPos)
{
*pHitPos = BTVEC_F3(cb.m_hitPointWorld);
}
return(pEnt->getId());
}
}
return(-1);
}
...@@ -257,7 +257,7 @@ LRESULT SXLevelEditor_RenderWindow_LClick(HWND hWnd, UINT uiMsg, WPARAM wParam, ...@@ -257,7 +257,7 @@ LRESULT SXLevelEditor_RenderWindow_LClick(HWND hWnd, UINT uiMsg, WPARAM wParam,
level_editor::GreenTraceSelect(); level_editor::GreenTraceSelect();
else if (level_editor::iActiveGroupType == EDITORS_LEVEL_GROUPTYPE_GAME && level_editor::idActiveElement >= 0) else if (level_editor::iActiveGroupType == EDITORS_LEVEL_GROUPTYPE_GAME && level_editor::idActiveElement >= 0)
{ {
level_editor::GameTraceSelect();
} }
else if (level_editor::iActiveGroupType == EDITORS_LEVEL_GROUPTYPE_AIGRID) else if (level_editor::iActiveGroupType == EDITORS_LEVEL_GROUPTYPE_AIGRID)
level_editor::AIGridTraceSelect(); level_editor::AIGridTraceSelect();
......
...@@ -249,6 +249,29 @@ void level_editor::GameSel(int iSelected) ...@@ -249,6 +249,29 @@ void level_editor::GameSel(int iSelected)
//level_editor::pAxesHelper->setScale(float3(1, 1, 1)); //level_editor::pAxesHelper->setScale(float3(1, 1, 1));
} }
void level_editor::GameTraceSelect()
{
float3 vResult;
ID idEnt = -1;
ID idMtrl = -1;
idEnt = SGame_EntGetByRay(vRayOrigin, vRayDir, &vResult);
if(ID_VALID(idEnt))
{
for(int i = 0, l = pListBoxList->getItemCount(); i < l; ++i)
{
if(pListBoxList->getItemData(i) == idEnt)
{
pListBoxList->setSel(i);
GameSel(i);
idMtl = idMtrl;
return;
}
}
}
}
void level_editor::GameTraceSetPos() void level_editor::GameTraceSetPos()
{ {
if (level_editor::iActiveGroupType != EDITORS_LEVEL_GROUPTYPE_GAME || level_editor::idActiveElement < 0) if (level_editor::iActiveGroupType != EDITORS_LEVEL_GROUPTYPE_GAME || level_editor::idActiveElement < 0)
......
...@@ -372,6 +372,8 @@ namespace level_editor ...@@ -372,6 +372,8 @@ namespace level_editor
//! listbox //! listbox
void GameSel(int iSelect); void GameSel(int iSelect);
void GameTraceSelect();
//! //!
void GameTraceSetPos(); void GameTraceSetPos();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment