diff --git a/source/SkyXEngine.h b/source/SkyXEngine.h index 17c3b78428d385a0498ced1a3b77dc7714af249a..ac4aa28b0f46e2c71420e180e675e4ca5a5cae3d 100644 --- a/source/SkyXEngine.h +++ b/source/SkyXEngine.h @@ -292,7 +292,7 @@ QT стиль документирования (!) и QT_AUTOBRIEF - корот #ifndef __SKYXENGINE_H #define __SKYXENGINE_H -#define SKYXENGINE_VERSION "X.1.2-dev" +#define SKYXENGINE_VERSION "X.1.3-dev" #define SKYXENGINE_VERSION4EDITORS "SkyXEngine version " ## SKYXENGINE_VERSION diff --git a/source/anim/AnimatedModel.cpp b/source/anim/AnimatedModel.cpp index a3c0574a1c977d2e1567700b04f3d8ff7905972f..94e86e768baa097b4c5a7c599da192538e610a80 100644 --- a/source/anim/AnimatedModel.cpp +++ b/source/anim/AnimatedModel.cpp @@ -408,7 +408,7 @@ float3 XMETHODCALLTYPE CAnimatedModel::getBoneTransformPos(UINT id) return(0); } - return(getOrientation() * ((m_pRenderFrameBones[id].position - m_pRenderFrameBones[id].orient * (float3)m_pShared->getInvertedBindPose()[id].position)) + getPosition()); + return(getOrientation() * ((m_pRenderFrameBones[id].position - m_pRenderFrameBones[id].orient * (float3)m_pShared->getInvertedBindPose()[id].position)) * m_fScale + getPosition()); } SMQuaternion XMETHODCALLTYPE CAnimatedModel::getBoneTransformRot(UINT id) { diff --git a/source/anim/AnimatedModelProvider.cpp b/source/anim/AnimatedModelProvider.cpp index 03b6405f66a0c2f8d61c34a700f0b7c9db715a6a..2b5c106a205f70bd4ef06903e705bcd0cdd171d8 100644 --- a/source/anim/AnimatedModelProvider.cpp +++ b/source/anim/AnimatedModelProvider.cpp @@ -172,3 +172,30 @@ void CAnimatedModelProvider::computeVisibility(const IFrustum *pFrustum, CRender } } } + +void CAnimatedModelProvider::getLevelSize(const XEventLevelSize *pData) +{ + CAnimatedModel *pMdl; + float3 vMax, vMin; + for(UINT i = 0, l = m_apModels.size(); i < l; ++i) + { + pMdl = m_apModels[i]; + if(pMdl->isEnabled()) + { + float3 vDelta = pMdl->getPosition(); + vMin = pMdl->getLocalBoundMin() + vDelta; + vMax = pMdl->getLocalBoundMax() + vDelta; + + if(pData->vMax == pData->vMin) + { + pData->vMax = vMax; + pData->vMin = vMin; + } + else + { + pData->vMax = SMVectorMax(pData->vMax, vMax); + pData->vMin = SMVectorMin(pData->vMin, vMin); + } + } + } +} diff --git a/source/anim/AnimatedModelProvider.h b/source/anim/AnimatedModelProvider.h index e8b64e8b7802525475afb462a14a1f77460c49cf..34a4cb0f67132fd16b2e8300c72ef650fc686a8a 100644 --- a/source/anim/AnimatedModelProvider.h +++ b/source/anim/AnimatedModelProvider.h @@ -28,6 +28,8 @@ public: void render(CRenderableVisibility *pVisibility = NULL); void computeVisibility(const IFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference=NULL); + void getLevelSize(const XEventLevelSize *pData); + protected: AssotiativeArray<IXResourceModelAnimated*, Array<CAnimatedModelShared*>> m_mModels; diff --git a/source/anim/DynamicModelProvider.cpp b/source/anim/DynamicModelProvider.cpp index de848979bc95536eb0cf015c0b4cad1a371cb54b..c75ee49dcb9839676b43b6a50ff1acd6302dca59 100644 --- a/source/anim/DynamicModelProvider.cpp +++ b/source/anim/DynamicModelProvider.cpp @@ -134,3 +134,31 @@ void CDynamicModelProvider::computeVisibility(const IFrustum *pFrustum, CRendera } } } + +void CDynamicModelProvider::getLevelSize(const XEventLevelSize *pData) +{ + CDynamicModel *pMdl; + float3 vMax, vMin; + for(UINT i = 0, l = m_apModels.size(); i < l; ++i) + { + pMdl = m_apModels[i]; + if(pMdl->isEnabled()) + { + float3 vDelta = pMdl->getPosition(); + vMin = pMdl->getLocalBoundMin() + vDelta; + vMax = pMdl->getLocalBoundMax() + vDelta; + + if(pData->vMax == pData->vMin) + { + pData->vMax = vMax; + pData->vMin = vMin; + } + else + { + pData->vMax = SMVectorMax(pData->vMax, vMax); + pData->vMin = SMVectorMin(pData->vMin, vMin); + } + + } + } +} diff --git a/source/anim/DynamicModelProvider.h b/source/anim/DynamicModelProvider.h index 154919fad6228d2eeb186fd54016f5ac0c72fd0d..99b9f8edba6155d54a8858149864a16cdad6bda6 100644 --- a/source/anim/DynamicModelProvider.h +++ b/source/anim/DynamicModelProvider.h @@ -26,6 +26,8 @@ public: void render(CRenderableVisibility *pVisibility = NULL); void computeVisibility(const IFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference=NULL); + void getLevelSize(const XEventLevelSize *pData); + protected: AssotiativeArray<IXResourceModel*, CDynamicModelShared*> m_mModels; diff --git a/source/anim/plugin_main.cpp b/source/anim/plugin_main.cpp index b60c5827285714b8f4e4e662b51e1e4f8870e903..da7832bca5216cde9224261595b31a7ae9291de4 100644 --- a/source/anim/plugin_main.cpp +++ b/source/anim/plugin_main.cpp @@ -1,23 +1,48 @@ #include <xcommon/IXPlugin.h> +#include <xcommon/XEvents.h> #include "Renderable.h" #include "Updatable.h" #include "AnimatedModelProvider.h" #include "DynamicModelProvider.h" +class CLevelSizeEventListener: public IEventListener<XEventLevelSize> +{ +public: + CLevelSizeEventListener(CAnimatedModelProvider *pAnimatedModelProvider, CDynamicModelProvider *pDynamicModelProvider): + m_pAnimatedModelProvider(pAnimatedModelProvider), + m_pDynamicModelProvider(pDynamicModelProvider) + { + } + void onEvent(const XEventLevelSize *pData) + { + m_pDynamicModelProvider->getLevelSize(pData); + m_pAnimatedModelProvider->getLevelSize(pData); + } + +protected: + CAnimatedModelProvider *m_pAnimatedModelProvider; + CDynamicModelProvider *m_pDynamicModelProvider; +}; class CDSEPlugin: public IXPlugin { public: void XMETHODCALLTYPE startup(IXCore *pCore) override { + m_pCore = pCore; m_pAnimatedModelProvider = new CAnimatedModelProvider(pCore); m_pDynamicModelProvider = new CDynamicModelProvider(pCore); m_pRenderable = new CRenderable(getID(), m_pAnimatedModelProvider, m_pDynamicModelProvider); m_pUpdatable = new CUpdatable(m_pAnimatedModelProvider); + m_pLevelSizeEventListener = new CLevelSizeEventListener(m_pAnimatedModelProvider, m_pDynamicModelProvider); + + m_pCore->getEventChannel<XEventLevelSize>(EVENT_LEVEL_GET_SIZE_GUID)->addListener(m_pLevelSizeEventListener); } void XMETHODCALLTYPE shutdown() override { + m_pCore->getEventChannel<XEventLevelSize>(EVENT_LEVEL_GET_SIZE_GUID)->removeListener(m_pLevelSizeEventListener); + mem_delete(m_pLevelSizeEventListener); mem_delete(m_pRenderable); mem_delete(m_pUpdatable); mem_delete(m_pAnimatedModelProvider); @@ -74,8 +99,10 @@ public: protected: CRenderable *m_pRenderable = NULL; CUpdatable *m_pUpdatable = NULL; + IXCore *m_pCore = NULL; CAnimatedModelProvider *m_pAnimatedModelProvider = NULL; CDynamicModelProvider *m_pDynamicModelProvider = NULL; + CLevelSizeEventListener *m_pLevelSizeEventListener = NULL; }; DECLARE_XPLUGIN(CDSEPlugin); diff --git a/source/core/ResourceManager.cpp b/source/core/ResourceManager.cpp index 1fc38c942dcfac3d0fd54c736a12481b41605b2c..b4995b525acb051c0c2490b8bffca982f49acd48 100644 --- a/source/core/ResourceManager.cpp +++ b/source/core/ResourceManager.cpp @@ -31,7 +31,7 @@ CResourceManager::CResourceManager(IXCore *pCore): strlwr(const_cast<char*>(sExt.getName())); sExt.setName(pLoader->getExt(i)); m_mapModelLoaders[sExt].push_back(pLoader); - m_aModelExts.push_back({pLoader->getDescription(), pLoader->getExt(i)}); + m_aModelExts.push_back({pLoader->getExtText(i), pLoader->getExt(i)}); } } } diff --git a/source/core/ResourceModel.cpp b/source/core/ResourceModel.cpp index 57a08e624b5c7829dcc97322d653b567cb690609..a77870ff45ae5a4ebd6db19a9bc71197568d7cb8 100644 --- a/source/core/ResourceModel.cpp +++ b/source/core/ResourceModel.cpp @@ -204,3 +204,8 @@ IModelPhysboxCapsule * XMETHODCALLTYPE CResourceModel::newPhysboxCapsule() const { return(new CModelPhysboxCapsule()); } + +void XMETHODCALLTYPE CResourceModel::setLocalAABB(const float3 &vMin, const float3 &vMax) +{ + //! @todo: implement me! +} diff --git a/source/core/ResourceModel.h b/source/core/ResourceModel.h index 3a668d6d57e8ad4b0e87cc0e6732499e3ef6822e..b18ff5f030cd18644d368d15f82fae684d904a2d 100644 --- a/source/core/ResourceModel.h +++ b/source/core/ResourceModel.h @@ -48,6 +48,8 @@ public: IModelPhysboxCylinder * XMETHODCALLTYPE newPhysboxCylinder() const override; IModelPhysboxCapsule * XMETHODCALLTYPE newPhysboxCapsule() const override; + void XMETHODCALLTYPE setLocalAABB(const float3 &vMin, const float3 &vMax) override; + void setFileName(const char *szFilename); const char *getFileName() const; diff --git a/source/dseplugin/ModelLoader.cpp b/source/dseplugin/ModelLoader.cpp index 018f8c847eb836179f1ef3742953b86baa7f3eb4..7b5f283a087c820f248c5663dd3a7e3f1c500e4f 100644 --- a/source/dseplugin/ModelLoader.cpp +++ b/source/dseplugin/ModelLoader.cpp @@ -1,16 +1,16 @@ #include "ModelLoader.h" #include "ModelFile.h" -UINT CModelLoader::getVersion() +UINT XMETHODCALLTYPE CModelLoader::getVersion() { return(IXMODELLOADER_VERSION); } -UINT CModelLoader::getExtCount() const +UINT XMETHODCALLTYPE CModelLoader::getExtCount() const { return(1); } -const char *CModelLoader::getExt(UINT uIndex) const +const char* XMETHODCALLTYPE CModelLoader::getExt(UINT uIndex) const { assert(uIndex < getExtCount()); switch(uIndex) @@ -20,20 +20,36 @@ const char *CModelLoader::getExt(UINT uIndex) const } return(NULL); } -const char *CModelLoader::getAuthor() const +const char* XMETHODCALLTYPE CModelLoader::getExtText(UINT uIndex) const +{ + assert(uIndex < getExtCount()); + switch(uIndex) + { + case 0: + return("SkyXEngine model"); + } + return(NULL); +} +const char* XMETHODCALLTYPE CModelLoader::getAuthor() const { return("D-AIRY @ DogmaNet"); } -const char *CModelLoader::getCopyright() const +const char* XMETHODCALLTYPE CModelLoader::getCopyright() const { return("Copyright © Vitaliy Buturlin, Evgeny Danilovich, 2019"); } -const char *CModelLoader::getDescription() const +const char* XMETHODCALLTYPE CModelLoader::getDescription() const { return("DSE model loader"); } -bool CModelLoader::open(IFile *pFile) +void XMETHODCALLTYPE CModelLoader::getInfo(XModelInfo *pModelInfo) +{ + assert(!"Not implemented!"); + //! @todo Implement me! +} + +bool XMETHODCALLTYPE CModelLoader::open(IFile *pFile) { assert(!m_pCurrentFile && "File already opened!"); if(m_pCurrentFile) @@ -66,11 +82,11 @@ bool CModelLoader::open(IFile *pFile) return(true); } -XMODELTYPE CModelLoader::getType() const +XMODELTYPE XMETHODCALLTYPE CModelLoader::getType() const { return((m_hdr.iFlags & MODEL_FLAG_STATIC) ? XMT_STATIC : XMT_ANIMATED); } -bool CModelLoader::loadAsStatic(IXResourceModelStatic *pResource) +bool XMETHODCALLTYPE CModelLoader::loadAsStatic(IXResourceModelStatic *pResource) { if(!loadGeneric(pResource)) { @@ -218,7 +234,7 @@ bool CModelLoader::loadAsStatic(IXResourceModelStatic *pResource) return(true); } -bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource) +bool XMETHODCALLTYPE CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource) { if(getType() != XMT_ANIMATED) { @@ -359,7 +375,7 @@ bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource) } for(UINT k = 0; k < pSubSet->iVertexCount; ++k) { - pSubSet->pVertices[k].vPos = (float3)(pSubSet->pVertices[k].vPos * 0.0254f); + pSubSet->pVertices[k].vPos = /*(float3)(*/pSubSet->pVertices[k].vPos/* * 0.0254f)*/; } } } @@ -388,7 +404,7 @@ bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource) { m_pCurrentFile->readBin(&mbn, sizeof(ModelBoneName)); assert(i == mbn.bone.id); - pResource->setBoneInfo(i, mbn.szName, mbn.bone.pid, mbn.bone.position * 0.0254f, mbn.bone.orient); + pResource->setBoneInfo(i, mbn.szName, mbn.bone.pid, mbn.bone.position/* * 0.0254f*/, mbn.bone.orient); } } @@ -459,7 +475,7 @@ bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource) m_pCurrentFile->readBin(&mb, sizeof(ModelBone)); pSequence->m_ppSequenceData[j][k].orient = mb.orient; - pSequence->m_ppSequenceData[j][k].position = (float3)(mb.position * 0.0254f); + pSequence->m_ppSequenceData[j][k].position = /*(float3)(*/mb.position/* * 0.0254f)*/; } } } @@ -503,7 +519,7 @@ bool CModelLoader::loadAsAnimated(IXResourceModelAnimated *pResource) return(true); } -void CModelLoader::close() +void XMETHODCALLTYPE CModelLoader::close() { m_pCurrentFile = NULL; } diff --git a/source/dseplugin/ModelLoader.h b/source/dseplugin/ModelLoader.h index 28e60f5d4a66fee1b8f5ed8ef7156ea2c4e9e4b3..cd9eb07196dbef055465d99c69c75557168011de 100644 --- a/source/dseplugin/ModelLoader.h +++ b/source/dseplugin/ModelLoader.h @@ -10,16 +10,17 @@ public: UINT XMETHODCALLTYPE getVersion() override; UINT XMETHODCALLTYPE getExtCount() const override; - const char * XMETHODCALLTYPE getExt(UINT uIndex) const override; - const char * XMETHODCALLTYPE getAuthor() const override; - const char * XMETHODCALLTYPE getCopyright() const override; - const char * XMETHODCALLTYPE getDescription() const override; + const char* XMETHODCALLTYPE getExt(UINT uIndex) const override; + const char* XMETHODCALLTYPE getExtText(UINT uIndex) const override; + const char* XMETHODCALLTYPE getAuthor() const override; + const char* XMETHODCALLTYPE getCopyright() const override; + const char* XMETHODCALLTYPE getDescription() const override; bool XMETHODCALLTYPE open(IFile *pFile) override; XMODELTYPE XMETHODCALLTYPE getType() const override; bool XMETHODCALLTYPE loadAsStatic(IXResourceModelStatic *pResource) override; bool XMETHODCALLTYPE loadAsAnimated(IXResourceModelAnimated *pResource) override; - // void XMETHODCALLTYPE getInfo() override; // ?? + void XMETHODCALLTYPE getInfo(XModelInfo *pModelInfo) override; void XMETHODCALLTYPE close() override; diff --git a/source/game/BaseAnimating.cpp b/source/game/BaseAnimating.cpp index 3f220492344cafbdfb34ec4d4ed79a55a23abab0..a0da87e2c2c2f90b900d8b66a3cb45d76b59fd0c 100644 --- a/source/game/BaseAnimating.cpp +++ b/source/game/BaseAnimating.cpp @@ -16,25 +16,22 @@ See the license in LICENSE BEGIN_PROPTABLE(CBaseAnimating) //! Файл модели. Поддерживаются статические и анимированные модели - DEFINE_FIELD_STRING(m_szModelFile, 0, "model", "Model file", EDITOR_FILEFIELD) - FILE_OPTION("Select model", "dse") - EDITOR_FILE_END() + DEFINE_FIELD_STRINGFN(m_szModelFile, 0, "model", "Model file", setModel, EDITOR_MODEL) //! Масштаб модели - // DEFINE_FIELD_FLOAT(m_fBaseScale, 0, "scale", "Scale", EDITOR_TEXTFIELD) + DEFINE_FIELD_FLOATFN(m_fBaseScale, 0, "scale", "Scale", setScale, EDITOR_TEXTFIELD) //! Объект референса для цвета свечения DEFINE_FIELD_ENTITY(m_pEntColorRef, 0, "glow_color_ref", "Glow color reference", EDITOR_TEXTFIELD) //! Цвет свечения DEFINE_FIELD_VECTOR(m_vGlowColor, 0, "glow_color", "Glow color", EDITOR_TEXTFIELD) - DEFINE_FIELD_BOOLFN(m_isStatic, 0, "is_static", "Is static", onIsStaticChange, EDITOR_COMBOBOX) - COMBO_OPTION("Yes", "1") - COMBO_OPTION("No", "0") - EDITOR_COMBO_END() + DEFINE_FIELD_BOOLFN(m_isStatic, 0, "is_static", "Is static", onIsStaticChange, EDITOR_YESNO) DEFINE_FIELD_INTFN(m_iSkin, 0, "skin", "Skin", setSkin, EDITOR_TEXTFIELD) + DEFINE_FIELD_BOOLFN(m_useAutoPhysbox, 0, "auto_physbox", "Auto generate physbox", onSetUseAutoPhysbox, EDITOR_YESNO) + DEFINE_INPUT(inputPlayAnim, "playAnim", "Play animation", PDF_STRING) DEFINE_INPUT(inputPlayAnimNext, "playAnimNext", "Play animation next", PDF_STRING) @@ -76,26 +73,14 @@ void CBaseAnimating::getMinMax(float3 * min, float3 * max) } }*/ -bool CBaseAnimating::setKV(const char * name, const char * value) +void CBaseAnimating::onSetUseAutoPhysbox(bool use) { - if(!BaseClass::setKV(name, value)) - { - return(false); - } - if(!strcmp(name, "model")) - { - setModel(value); - } - /*else if(!strcmp(name, "scale")) + if(m_useAutoPhysbox != use) { + m_useAutoPhysbox = use; releasePhysics(); - if(m_pAnimPlayer) - { - m_pAnimPlayer->setScale(m_fBaseScale); - } initPhysics(); - }*/ - return(true); + } } void CBaseAnimating::setModel(const char * mdl) @@ -119,10 +104,23 @@ void CBaseAnimating::setModel(const char * mdl) { m_pModel = pModel; m_pModel->setSkin(m_iSkin); + m_pModel->setScale(m_fBaseScale); } mem_release(pResource); } - + + initPhysics(); +} + +void CBaseAnimating::setScale(float fScale) +{ + m_fBaseScale = fScale; + + releasePhysics(); + if(m_pModel) + { + m_pModel->setScale(m_fBaseScale); + } initPhysics(); } @@ -218,16 +216,16 @@ void CBaseAnimating::initPhysics() switch(pPhysbox->getType()) { case XPBT_BOX: - pLocalShape = new btBoxShape(F3_BTVEC(pPhysbox->asBox()->getSize())); + pLocalShape = new btBoxShape(F3_BTVEC(pPhysbox->asBox()->getSize()) * m_fBaseScale); break; case XPBT_SPHERE: - pLocalShape = new btSphereShape(pPhysbox->asSphere()->getRadius()); + pLocalShape = new btSphereShape(pPhysbox->asSphere()->getRadius() * m_fBaseScale); break; case XPBT_CAPSULE: - pLocalShape = new btCapsuleShape(pPhysbox->asCapsule()->getRadius(), pPhysbox->asCapsule()->getHeight()); + pLocalShape = new btCapsuleShape(pPhysbox->asCapsule()->getRadius() * m_fBaseScale, pPhysbox->asCapsule()->getHeight() * m_fBaseScale); break; case XPBT_CYLINDER: - pLocalShape = new btCylinderShape(btVector3(pPhysbox->asCylinder()->getRadius(), pPhysbox->asCylinder()->getHeight() * 0.5f, pPhysbox->asCylinder()->getRadius())); + pLocalShape = new btCylinderShape(btVector3(pPhysbox->asCylinder()->getRadius(), pPhysbox->asCylinder()->getHeight() * 0.5f, pPhysbox->asCylinder()->getRadius()) * m_fBaseScale); break; case XPBT_CONVEX: { @@ -237,6 +235,10 @@ void CBaseAnimating::initPhysics() btVector3 *pData; int iVertexCount; SPhysics_BuildHull(&tmpShape, &pData, &iVertexCount); + for(int i = 0; i < iVertexCount; ++i) + { + pData[i] *= m_fBaseScale; + } pLocalShape = new btConvexHullShape((float*)pData, iVertexCount, sizeof(btVector3)); SPhysics_ReleaseHull(pData, iVertexCount); } @@ -245,11 +247,11 @@ void CBaseAnimating::initPhysics() if(pLocalShape) { - btTransform localTransform(Q4_BTQUAT(pPhysbox->getOrientation()), F3_BTVEC(pPhysbox->getPosition())); + btTransform localTransform(Q4_BTQUAT(pPhysbox->getOrientation()), F3_BTVEC(pPhysbox->getPosition()) * m_fBaseScale); pShape->addChildShape(localTransform, pLocalShape); } } - if(!uShapesCount) + if(!uShapesCount && m_useAutoPhysbox) { { auto pResource = m_pModel->getResource()->asStatic(); @@ -266,6 +268,10 @@ void CBaseAnimating::initPhysics() btVector3 *pData; int iVertexCount; SPhysics_BuildHull(&tmpShape, &pData, &iVertexCount); + for(int i = 0; i < iVertexCount; ++i) + { + pData[i] *= m_fBaseScale; + } pLocalShape = new btConvexHullShape((float*)pData, iVertexCount, sizeof(btVector3)); SPhysics_ReleaseHull(pData, iVertexCount); @@ -294,6 +300,10 @@ void CBaseAnimating::initPhysics() btVector3 *pData; int iVertexCount; SPhysics_BuildHull(&tmpShape, &pData, &iVertexCount); + for(int i = 0; i < iVertexCount; ++i) + { + pData[i] *= m_fBaseScale; + } pLocalShape = new btConvexHullShape((float*)pData, iVertexCount, sizeof(btVector3)); SPhysics_ReleaseHull(pData, iVertexCount); diff --git a/source/game/BaseAnimating.h b/source/game/BaseAnimating.h index 1ce44957072aced7dabf4cc5b5606b1fb5e3c8a0..63fe6a72e4bd954b9b8bd158009efe75bb8aee3b 100644 --- a/source/game/BaseAnimating.h +++ b/source/game/BaseAnimating.h @@ -32,9 +32,8 @@ public: void getMinMax(float3 * min, float3 * max); // void getSphere(float3 * center, float * radius); - bool setKV(const char * name, const char * value); - - virtual void setModel(const char * mdl); + virtual void setModel(const char *szMdl); + virtual void setScale(float fScale); float3 getAttachmentPos(int id); SMQuaternion getAttachmentRot(int id); @@ -74,8 +73,9 @@ protected: IXModel *m_pModel = NULL; const char * m_szModelFile; - // float m_fBaseScale; + float m_fBaseScale = 1.0f; bool m_isStatic = false; + bool m_useAutoPhysbox = true; CBaseEntity *m_pEntColorRef = NULL; float3_t m_vGlowColor; @@ -93,7 +93,7 @@ protected: virtual void onAnimationStateChanged(int slot, ANIM_STATE as); void onIsStaticChange(bool isStatic); - + void onSetUseAutoPhysbox(bool use); int m_iSkin = 0; struct diff --git a/source/game/BaseItem.cpp b/source/game/BaseItem.cpp index b99265a8d1666dbc3852057d19aa789a5a69645e..330603b52766bdb683cee1ba05a7dc2d304319ba 100644 --- a/source/game/BaseItem.cpp +++ b/source/game/BaseItem.cpp @@ -29,9 +29,7 @@ BEGIN_PROPTABLE(CBaseItem) DEFINE_OUTPUT(m_onPickUp, "OnPickUp", "On pickup") DEFINE_OUTPUT(m_onDrop, "OnDrop", "On drop") - DEFINE_FIELD_STRINGFN(m_szViewModelFile, 0, "model_view", "View model file", onSetViewModel, EDITOR_FILEFIELD) - FILE_OPTION("Select model", "dse") - EDITOR_FILE_END() + DEFINE_FIELD_STRINGFN(m_szViewModelFile, 0, "model_view", "View model file", onSetViewModel, EDITOR_MODEL) END_PROPTABLE() REGISTER_ENTITY_NOLISTING(CBaseItem, base_item); @@ -116,6 +114,16 @@ void CBaseItem::onModeChanged(INVENTORY_ITEM_MODE oldMode, INVENTORY_ITEM_MODE n } } +void CBaseItem::setScale(float fScale) +{ + BaseClass::setScale(fScale); + + if(m_pViewModel) + { + m_pViewModel->setScale(fScale); + } +} + void CBaseItem::onSetViewModel(const char *mdl) { _setStrVal(&m_szViewModelFile, mdl); @@ -168,6 +176,7 @@ void CBaseItem::onModelChanged() { m_pViewModel->play("IDLE"); m_pViewModel->enable(m_inventoryMode == IIM_EQUIPPED); + m_pViewModel->setScale(m_fBaseScale); } } } diff --git a/source/game/BaseItem.h b/source/game/BaseItem.h index 45cd17ee7268fbe6e465dcab0ec79c7b308021f8..e15bc0a41d11d6999f90d60583475db30afdfa36 100644 --- a/source/game/BaseItem.h +++ b/source/game/BaseItem.h @@ -50,6 +50,8 @@ protected: void onModelChanged(); void onSync() override; + void setScale(float fScale) override; + const char * m_szInvName; //!< Имя, отображаемое в инвентаре bool m_bInvStackable; //!< Можно ли хранить несколько итемов в одной ячейке int m_iInvStackCurSize; //!< Количество итемов в стеке diff --git a/source/game/PropStatic.cpp b/source/game/PropStatic.cpp index 2d0a51f332a11073ab778c68d468207d456cba3a..af65c15cdd7248f7a77ad66d49cd17582608b463 100644 --- a/source/game/PropStatic.cpp +++ b/source/game/PropStatic.cpp @@ -11,14 +11,7 @@ See the license in LICENSE */ BEGIN_PROPTABLE(CPropStatic) - //! Масштаб модели - DEFINE_FIELD_FLOATFN(m_fScale, 0, "scale", "Scale", onSetScale, EDITOR_TEXTFIELD) - - - DEFINE_FIELD_BOOLFN(m_useTrimeshPhysics, 0, "use_trimesh", "Use trimesh physics", onSetUseTrimesh, EDITOR_COMBOBOX) - COMBO_OPTION("Yes", "1") - COMBO_OPTION("No", "0") - EDITOR_COMBO_END() + DEFINE_FIELD_BOOLFN(m_useTrimeshPhysics, 0, "use_trimesh", "Use trimesh physics", onSetUseTrimesh, EDITOR_YESNO) END_PROPTABLE() REGISTER_ENTITY(CPropStatic, prop_static); @@ -65,15 +58,6 @@ void CPropStatic::removePhysBody() mem_delete(m_pRigidBody); } -void CPropStatic::onSetScale(float fScale) -{ - m_fScale = fScale; - if(m_pModel) - { - m_pModel->setScale(fScale); - } -} - void CPropStatic::initPhysics() { if(!m_pModel) @@ -92,6 +76,11 @@ void CPropStatic::initPhysics() return; } + if(!m_useAutoPhysbox) + { + return; + } + btCompoundShape *pShape = new btCompoundShape(true, uShapesCount); auto pResource = m_pModel->getResource()->asStatic(); @@ -105,6 +94,7 @@ void CPropStatic::initPhysics() if(pLocalShape) { + pLocalShape->setLocalScaling(btVector3(m_fBaseScale, m_fBaseScale, m_fBaseScale)); btTransform localTransform; localTransform.setIdentity(); pShape->addChildShape(localTransform, pLocalShape); @@ -137,16 +127,6 @@ void CPropStatic::releasePhysics() } } -void CPropStatic::setModel(const char *mdl) -{ - BaseClass::setModel(mdl); - - if(m_pModel) - { - m_pModel->setScale(m_fScale); - } -} - void CPropStatic::onSetUseTrimesh(bool use) { if(m_useTrimeshPhysics != use) diff --git a/source/game/PropStatic.h b/source/game/PropStatic.h index c4daf11915aa0193e885e04724ce391bc63de3ed..5a658406a4e98177d767c5cb9b38f6f7dd2ededf 100644 --- a/source/game/PropStatic.h +++ b/source/game/PropStatic.h @@ -25,17 +25,14 @@ public: DECLARE_CONSTRUCTOR(); ~CPropStatic(); +protected: void createPhysBody() override; void removePhysBody() override; void initPhysics() override; void releasePhysics() override; - void setModel(const char *mdl) override; -protected: - void onSetScale(float fScale); void onSetUseTrimesh(bool use); - float m_fScale = 1.0f; bool m_useTrimeshPhysics = false; }; diff --git a/source/game/proptable.h b/source/game/proptable.h index 19049e341dc47019c611bc72ca9e585b43ac190b..1bb41c1a5c180d3057aabf959bdb243c6cc9e84d 100644 --- a/source/game/proptable.h +++ b/source/game/proptable.h @@ -364,6 +364,8 @@ const char * GetEmptyString(); #define FILE_OPTION(name, value) , name, value #define EDITOR_FILE_END() , NULL)} +#define EDITOR_YESNO EDITOR_COMBOBOX COMBO_OPTION("Yes", "1") COMBO_OPTION("No", "0") EDITOR_COMBO_END() +#define EDITOR_MODEL EDITOR_FILEFIELD FILE_OPTION("Select model", "dse") EDITOR_FILE_END() #define DEFINE_FIELD_STRING(field, flags, keyname, edname, editor) , {(fieldtype)&DataClass::field, PDF_STRING, flags, keyname, edname, editor #define DEFINE_FIELD_VECTOR(field, flags, keyname, edname, editor) , {(fieldtype)&DataClass::field, PDF_VECTOR, flags, keyname, edname, editor diff --git a/source/xcommon/IXModelLoader.h b/source/xcommon/IXModelLoader.h index 957cf91994a295ff892fac9957c790ebdd212d61..ef3ef105e7b9ad62812aa9efb9ee8349a86c5399 100644 --- a/source/xcommon/IXModelLoader.h +++ b/source/xcommon/IXModelLoader.h @@ -9,11 +9,46 @@ #define IXMODELLOADER_GUID DEFINE_XGUID(0x8e7da1d6, 0x7965, 0x41a1, 0xbf, 0xb4, 0x7, 0xb0, 0x87, 0xe8, 0x54, 0xa1) #define IXMODELLOADER_VERSION 1 +//! возможная информация о dse файле +struct XModelInfo +{ + //! тип файла + XMODELTYPE type; + + //! количество вершин + UINT uVertexCount; + + //! количество индексов + UINT uIndexCount; + + //! количество подгрупп + UINT uSubsetsCount; + + //! количество скинов + UINT uSkinCount; + + //! количество хитбоксов + UINT uHitboxCount; + + //! количество костей + UINT uBoneCount; + + //! количетсов анимаций + UINT uAnimationCount; + + //! габариты в метрах + float3_t vDimensions; + + //! центр модели в метрах + float3_t vCenter; +}; + class IXModelLoader: public IXUnknown { public: virtual UINT XMETHODCALLTYPE getExtCount() const = 0; virtual const char* XMETHODCALLTYPE getExt(UINT uIndex) const = 0; + virtual const char* XMETHODCALLTYPE getExtText(UINT uIndex) const = 0; virtual const char* XMETHODCALLTYPE getAuthor() const = 0; virtual const char* XMETHODCALLTYPE getCopyright() const = 0; virtual const char* XMETHODCALLTYPE getDescription() const = 0; @@ -22,7 +57,7 @@ public: virtual XMODELTYPE XMETHODCALLTYPE getType() const = 0; virtual bool XMETHODCALLTYPE loadAsStatic(IXResourceModelStatic *pResource) = 0; virtual bool XMETHODCALLTYPE loadAsAnimated(IXResourceModelAnimated *pResource) = 0; - // virtual void XMETHODCALLTYPE getInfo() = 0; // ?? + virtual void XMETHODCALLTYPE getInfo(XModelInfo *pModelInfo) = 0; virtual void XMETHODCALLTYPE close() = 0; }; diff --git a/source/xcommon/resource/IXResourceModel.h b/source/xcommon/resource/IXResourceModel.h index 6bd94b674411997a01acb250eb16da669d14f256..0ed5a3925627406d5dc94956c21c2a80a4d38bde 100644 --- a/source/xcommon/resource/IXResourceModel.h +++ b/source/xcommon/resource/IXResourceModel.h @@ -280,6 +280,8 @@ public: virtual UINT XMETHODCALLTYPE addLod(UINT uSubsetCount, UINT *puVertexCount, UINT *puIndexCount) = 0; virtual UINT XMETHODCALLTYPE getLodCount() const = 0; + virtual void XMETHODCALLTYPE setLocalAABB(const float3 &vMin, const float3 &vMax) = 0; + virtual bool XMETHODCALLTYPE validate() const = 0; virtual IModelPhysboxBox * XMETHODCALLTYPE newPhysboxBox() const = 0;