Commit 2d4478bd authored by D-AIRY's avatar D-AIRY

Fixed light point; footstep sounds for player

parent 9409b605
common @ 9e2fad2b
Subproject commit 358f676071d7a332e43f43870e461e3882dab5fb
Subproject commit 9e2fad2b1cfdb91901ed176b1a2e6417b835a320
......@@ -3,6 +3,8 @@
#include "Ragdoll.h"
#include <score/sxscore.h>
SXplayer * GameData::m_pPlayer;
SXpointCamera * GameData::m_pActiveCamera;
......@@ -13,6 +15,8 @@ IAnimPlayer * pl;
GameData::GameData()
{
loadFoostepsSounds();
m_pMgr = new EntityManager();
Core_0RegisterConcmd("+forward", ccmd_forward_on);
......@@ -84,6 +88,12 @@ GameData::~GameData()
//mem_delete(g_pRagdoll);
mem_delete(m_pMgr);
for(int i = 0; i < MPT_COUNT; ++i)
{
// @TODO: SSCore_SndDelete3dInst()
mem_delete_a(m_pidFootstepSound[i]);
}
}
void GameData::Update()
......@@ -102,6 +112,67 @@ void GameData::Sync()
m_pCrosshair->OnSync();
}
void GameData::playFootstepSound(MtlPhysicType mtl_type, const float3 &f3Pos)
{
int iCount = m_iFootstepSoundCount[mtl_type];
if(!iCount)
{
return;
}
ID idSound = m_pidFootstepSound[mtl_type][rand() % iCount];
SSCore_SndInstancePlay3d(idSound, (float3*)&f3Pos);
}
void GameData::loadFoostepsSounds()
{
Array<const char*> aSounds[MPT_COUNT];
aSounds[mpt_concrete].push_back("actor/step/default1.ogg");
aSounds[mpt_concrete].push_back("actor/step/default2.ogg");
aSounds[mpt_concrete].push_back("actor/step/default3.ogg");
aSounds[mpt_concrete].push_back("actor/step/default4.ogg");
aSounds[mpt_metal].push_back("actor/step/metal_plate1.ogg");
aSounds[mpt_metal].push_back("actor/step/metal_plate2.ogg");
aSounds[mpt_metal].push_back("actor/step/metal_plate3.ogg");
aSounds[mpt_metal].push_back("actor/step/metal_plate4.ogg");
aSounds[mpt_tree].push_back("actor/step/new_wood1.ogg");
aSounds[mpt_tree].push_back("actor/step/new_wood2.ogg");
aSounds[mpt_tree].push_back("actor/step/new_wood3.ogg");
aSounds[mpt_tree].push_back("actor/step/new_wood4.ogg");
aSounds[mpt_ground_sand].push_back("actor/step/earth1.ogg");
aSounds[mpt_ground_sand].push_back("actor/step/earth2.ogg");
aSounds[mpt_ground_sand].push_back("actor/step/earth3.ogg");
aSounds[mpt_ground_sand].push_back("actor/step/earth4.ogg");
aSounds[mpt_water].push_back("actor/step/t_water1.ogg");
aSounds[mpt_water].push_back("actor/step/t_water2.ogg");
aSounds[mpt_leaf_grass].push_back("actor/step/grass1.ogg");
aSounds[mpt_leaf_grass].push_back("actor/step/grass2.ogg");
aSounds[mpt_leaf_grass].push_back("actor/step/grass3.ogg");
aSounds[mpt_leaf_grass].push_back("actor/step/grass4.ogg");
//aSounds[mpt_glass].push_back("actor/step/.ogg");
//aSounds[mpt_plastic].push_back("actor/step/.ogg");
//aSounds[mpt_flesh].push_back("actor/step/.ogg");
for(int i = 0; i < MPT_COUNT; ++i)
{
Array<const char*> *paSounds = &aSounds[i];
int jl = paSounds->size();
m_iFootstepSoundCount[i] = jl;
m_pidFootstepSound[i] = jl ? new ID[jl] : NULL;
for(int j = 0; j < jl; ++j)
{
m_pidFootstepSound[i][j] = SSCore_SndCreate3dInst(paSounds[0][j], false, 0, 100);
}
}
}
//###################################################################
void GameData::ccmd_forward_on()
{
......
......@@ -4,6 +4,7 @@
#include "SXplayer.h"
#include "crosshair.h"
#include <mtllight/sxmtllight.h>
class GameData
{
......@@ -23,8 +24,15 @@ public:
void RenderHUD();
void Sync();
void playFootstepSound(MtlPhysicType mtl_type, const float3 &f3Pos);
protected:
void loadFoostepsSounds();
ID *m_pidFootstepSound[MPT_COUNT];
int m_iFootstepSoundCount[MPT_COUNT];
static void ccmd_forward_on();
static void ccmd_forward_off();
......@@ -65,4 +73,6 @@ protected:
};
extern GameData * g_pGameData;
#endif
......@@ -20,6 +20,7 @@ BEGIN_PROPTABLE(CLightPoint)
DEFINE_OUTPUT(m_onTurnOn, "OnTurnOn", "On Turn On")
DEFINE_OUTPUT(m_onTurnOff, "OnTurnOff", "On Turn Off")
DEFINE_FLAG(LIGHT_INITIALLY_DARK, "Initially dark")
END_PROPTABLE()
REGISTER_ENTITY(CLightPoint, light_point);
......@@ -85,7 +86,7 @@ void CLightPoint::turnOn(inputdata_t * pInputdata)
void CLightPoint::turnOff(inputdata_t * pInputdata)
{
if(!m_isEnable)
if(m_isEnable)
{
m_isEnable = false;
FIRE_OUTPUT(m_onTurnOff, pInputdata->pInflictor);
......
......@@ -4,6 +4,8 @@
#include "SXpointEntity.h"
#define LIGHT_INITIALLY_DARK 0x00010000
class CLightPoint : public SXpointEntity
{
DECLARE_CLASS(CLightPoint, SXpointEntity);
......
......@@ -46,6 +46,7 @@ void CNPCBase::InitPhysics()
m_pCollideShape = new btCapsuleShape(0.3f, 1.4f);
m_pGhostObject->setCollisionShape(m_pCollideShape);
m_pGhostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
m_pGhostObject->setUserPointer(this);
m_pCharacter = new btKinematicCharacterController(m_pGhostObject, (btConvexShape*)m_pCollideShape, m_fStepHeight, btVector3(0.0f, 1.0f, 0.0f));
m_pCharacter->setMaxJumpHeight(0.60f);
......
......@@ -136,10 +136,11 @@ void SXbaseAnimating::PlayAnimation(const char * name, UINT iFadeTime, UINT slot
bool SXbaseAnimating::PlayingAnimations(const char* name)
{
if (m_pAnimPlayer)
if(m_pAnimPlayer)
{
return m_pAnimPlayer->PlayingAnimations(name);
return(m_pAnimPlayer->PlayingAnimations(name));
}
return(false);
}
void SXbaseAnimating::PlayActivity(const char * name, UINT iFadeTime, UINT slot)
......
......@@ -5,12 +5,38 @@
#include "SXbaseTool.h"
#include <aigrid/sxaigrid.h>
#include "GameData.h"
BEGIN_PROPTABLE(SXplayer)
// empty
END_PROPTABLE()
REGISTER_ENTITY(SXplayer, player);
class btKinematicClosestNotMeRayResultCallback: public btCollisionWorld::ClosestRayResultCallback
{
public:
btKinematicClosestNotMeRayResultCallback(btCollisionObject* me, const btVector3& rayFromWorld, const btVector3& rayToWorld): btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld)
{
m_me = me;
m_shapeInfo = {-1, -1};
}
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
{
if(rayResult.m_collisionObject == m_me)
return 1.0;
if(rayResult.m_localShapeInfo)
{
m_shapeInfo = *rayResult.m_localShapeInfo;
}
return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
}
btCollisionWorld::LocalShapeInfo m_shapeInfo;
protected:
btCollisionObject* m_me;
};
SXplayer::SXplayer(EntityManager * pMgr):
BaseClass(pMgr),
m_uMoveDir(PM_OBSERVER),
......@@ -72,9 +98,10 @@ SXplayer::SXplayer(EntityManager * pMgr):
m_flashlight = (CLightDirectional*)CREATE_ENTITY("light_directional", m_pMgr);
m_flashlight->SetPos(GetPos() + float3(0.f, 0.1f, 0.f));
m_flashlight->SetOrient(GetOrient() * SMQuaternion(SM_PI*0.5f, 'x'));
m_flashlight->SetOrient(GetOrient() * SMQuaternion(SM_PIDIV2, 'x'));
m_flashlight->SetParent(this);
m_flashlight->setDist(10.f);
m_flashlight->setDist(20.f);
m_flashlight->setAngle(SMToRadian(60));
m_flashlight->setColor(float3(3.5, 3.5, 3.5));
m_flashlight->setShadowType(-1);
......@@ -90,6 +117,26 @@ SXplayer::~SXplayer()
REMOVE_ENTITY(m_pCamera);
}
void SXplayer::playFootstepsSound()
{
if(!(m_uMoveDir & PM_OBSERVER))
{
if(onGround())
{
float3 start = GetPos(),
end = start + float3(0.0f, -2.0f, 0.0f);
btKinematicClosestNotMeRayResultCallback cb(m_pGhostObject, F3_BTVEC(start), F3_BTVEC(end));
SXPhysics_GetDynWorld()->rayTest(F3_BTVEC(start), F3_BTVEC(end), cb);
if(cb.hasHit() && cb.m_shapeInfo.m_shapePart == 0 && cb.m_shapeInfo.m_triangleIndex >= 0)
{
MtlPhysicType type = (MtlPhysicType)SXPhysics_GetMtlType(cb.m_collisionObject, &cb.m_shapeInfo);
g_pGameData->playFootstepSound(type, BTVEC_F3(cb.m_hitPointWorld));
}
}
}
}
void SXplayer::UpdateInput(float dt)
{
int x, y;
......@@ -196,6 +243,7 @@ void SXplayer::UpdateInput(float dt)
{
if(m_canJump)
{
playFootstepsSound();
m_pCharacter->jump();
m_canJump = false;
}
......@@ -225,6 +273,10 @@ void SXplayer::UpdateInput(float dt)
{
if(mov && m_pCharacter->onGround())
{
const float fFS1 = SM_PIDIV2;
const float fFS2 = SM_PI + SM_PIDIV2;
bool bFS1 = m_fViewbobStep < fFS1;
bool bFS2 = m_fViewbobStep < fFS2;
if(m_uMoveDir & PM_RUN)
{
m_fViewbobStep += dt * *cl_bob_run * 0.2f;
......@@ -233,6 +285,11 @@ void SXplayer::UpdateInput(float dt)
{
m_fViewbobStep += dt * *cl_bob_walk;
}
if((bFS1 && m_fViewbobStep > fFS1) || (bFS2 && m_fViewbobStep > fFS2))
{
playFootstepsSound();
}
//printf("%f\n", m_fViewbobStep);
while(m_fViewbobStep > SM_2PI)
{
m_fViewbobStep -= SM_2PI;
......
......@@ -65,6 +65,8 @@ public:
bool onGround();
void playFootstepsSound();
protected:
CLightDirectional* m_flashlight;
......
......@@ -19,6 +19,8 @@ enum PDF_TYPE
PDF_PARENT,
PDF_FLAGS,
PDF_FLAG,
PDF_OUTPUT
};
......@@ -28,7 +30,8 @@ enum PDE_TYPE
PDE_NONE = 0,
PDE_TEXTFIELD,
PDE_COMBOBOX,
PDE_FILEFIELD
PDE_FILEFIELD,
PDE_FLAGS
};
enum PDF_FLAG
......@@ -285,4 +288,6 @@ const char * GetEmptyString();
#define DEFINE_INPUT(method, keyname, edname, argtype) , {(input_func)&DataClass::method, argtype, PDFF_NOEDIT | PDFF_INPUT, keyname, edname, EDITOR_NONE
#define DEFINE_OUTPUT(field, keyname, edname) , {(fieldtype)&DataClass::field, PDF_OUTPUT, PDFF_NOEDIT | PDFF_OUTPUT, keyname, edname, EDITOR_NONE
#define DEFINE_FLAG(value, edname) , {(fieldtype)NULL, PDF_FLAG, value, NULL, edname, {PDE_FLAGS, NULL}}
#endif
......@@ -85,17 +85,10 @@ void Level::Load(const char* name)
{
char tmppath[1024];
sprintf(tmppath, "%s%s\\%s", Core_RStringGet(G_RI_STRING_PATH_GS_LEVELS), name, config->getKey("level", "physic"));
if(Core_0FileExists(tmppath))
{
SXPhysics_ImportGeom(tmppath);
}
else
{
#if defined(SX_GAME)
SXPhysics_LoadGeom();
SXPhysics_ExportGeom(tmppath);
#endif
}
//if(Core_0FileExists(tmppath))
//{
SXPhysics_LoadGeom(tmppath);
//}
}
else
{
......
......@@ -611,6 +611,10 @@ enum MtlTypeModel
enum MtlPhysicType
{
mpt_concrete = 0, //!< бетон
//! значение по умолчанию
mpt_default = mpt_concrete,
mpt_metal, //!< металл
mpt_glass, //!< стекло
mpt_plastic, //!< пластик
......@@ -620,8 +624,8 @@ enum MtlPhysicType
mpt_water, //!< вода
mpt_leaf_grass, //!< листва/трава
//! значение по умолчанию
mpt_default = mpt_concrete,
//! количество типов
MPT_COUNT
};
//! данные отправляемые в шейдеры
......
......@@ -11,7 +11,8 @@ PhyWorld::PhyWorld():
m_pGeomStaticCollideMesh(NULL),
m_pGeomStaticCollideShape(NULL),
m_pGeomStaticRigidBody(NULL),
m_ppGeomMtlTypes(0),
m_pGeomMtlTypes(0),
m_iGeomFacesCount(0),
m_iGeomModelCount(0),
m_ppGreenStaticCollideShape(NULL),
m_pppGreenStaticRigidBody(NULL),
......@@ -111,7 +112,13 @@ void PhyWorld::LoadGeom(const char * file)
SGeom_ModelsGetArrBuffsGeom(&ppVertices, &pVertexCount, &ppIndices, &ppMtls, &pIndexCount, &iModelCount);
if(iModelCount > 0)
{
m_ppGeomMtlTypes = new int*[iModelCount];
m_iGeomFacesCount = 0;
for(int32_t tc = 0; tc < iModelCount; ++tc)
{
m_iGeomFacesCount += pIndexCount[tc] / 3;
}
m_pGeomMtlTypes = new MtlPhysicType[m_iGeomFacesCount];
m_iGeomModelCount = iModelCount;
m_pGeomStaticCollideMesh = new btTriangleMesh(true, false);
......@@ -129,17 +136,16 @@ void PhyWorld::LoadGeom(const char * file)
IC = 0;
VC = 0;
int32_t iFace = 0;
for(int32_t tc = 0; tc < iModelCount; ++tc)
{
m_ppGeomMtlTypes[tc] = new int[pIndexCount[tc] / 3];
for(int i = 0; i < pVertexCount[tc]; ++i)
{
m_pGeomStaticCollideMesh->findOrAddVertex(F3_BTVEC(ppVertices[tc][i]), false);
}
for(int i = 0; i < pIndexCount[tc]; i += 3)
{
m_ppGeomMtlTypes[tc][i / 3] = SML_MtlGetPhysicMaterial(ppMtls[tc][i]);
m_pGeomMtlTypes[iFace++] = SML_MtlGetPhysicMaterial(ppMtls[tc][i]);
m_pGeomStaticCollideMesh->addTriangleIndices(ppIndices[tc][i] + VC, ppIndices[tc][i + 1] + VC, ppIndices[tc][i + 2] + VC);
}
IC += pIndexCount[tc];
......@@ -361,6 +367,8 @@ void PhyWorld::LoadGeom(const char * file)
}
SGeom_GreenClearNavMeshAndTransform(green_arr_vertex, green_arr_count_vertex, green_arr_index, green_arr_mtl, green_arr_count_index, green_arr_transform, green_arr_count_transform, green_arr_count_green);
ExportGeom(file);
}
void PhyWorld::UnloadGeom()
......@@ -395,17 +403,25 @@ void PhyWorld::UnloadGeom()
mem_delete(m_pGeomStaticCollideShape);
mem_delete(m_pGeomStaticCollideMesh);
for(int i = 0; i < m_iGeomModelCount; ++i)
{
mem_delete_a(m_ppGeomMtlTypes[i]);
}
m_iGeomModelCount = 0;
mem_delete_a(m_ppGeomMtlTypes);
m_iGeomFacesCount = 0;
mem_delete_a(m_pGeomMtlTypes);
}
bool PhyWorld::ImportGeom(const char * file)
{
UnloadGeom();
int len = strlen(file) + 1;
char * name = (char*)alloca(sizeof(char)*(len + 1));
memcpy(name, file, sizeof(char)* len);
name[len - 1] = 'm';
name[len] = 0;
if(!Core_0FileExists(file) || !Core_0FileExists(name))
{
return(false);
}
btBulletWorldImporter * importer = new btBulletWorldImporter(m_pDynamicsWorld);
......@@ -449,8 +465,40 @@ bool PhyWorld::ImportGeom(const char * file)
}
}
}
FILE *pF = fopen(name, "rb");
if(pF)
{
PhyMatFile pmf;
if(fread(&pmf, sizeof(pmf), 1, pF))
{
if(pmf.i64Magick == PHY_MAT_FILE_MAGICK)
{
m_iGeomFacesCount = pmf.uiGeomFaceCount;
m_pGeomMtlTypes = new MtlPhysicType[m_iGeomFacesCount];
fread(m_pGeomMtlTypes, sizeof(MtlPhysicType), m_iGeomFacesCount, pF);
}
else
{
ret = false;
}
}
else
{
ret = false;
}
fclose(pF);
}
else
{
ret = false;
}
}
mem_delete(importer);
if(!ret)
{
UnloadGeom();
}
return(ret);
}
......@@ -491,9 +539,38 @@ bool PhyWorld::ExportGeom(const char * _file)
&& fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file)
&& !fclose(file);
mem_delete(serializer);
int len = strlen(_file)+1;
char * name = (char*)alloca(sizeof(char)*(len + 1));
memcpy(name, _file, sizeof(char)* len);
name[len - 1] = 'm';
name[len] = 0;
file = fopen(name, "wb");
if(!file)
{
ret = false;
}
else
{
PhyMatFile pmf;
pmf.uiGeomFaceCount = m_iGeomFacesCount;
fwrite(&pmf, sizeof(pmf), 1, file);
fwrite(m_pGeomMtlTypes, sizeof(MtlPhysicType), m_iGeomFacesCount, file);
fclose(file);
}
return(ret);
}
MtlPhysicType PhyWorld::GetMtlType(const btCollisionObject *pBody, const btCollisionWorld::LocalShapeInfo *pShapeInfo)
{
if(pBody == m_pGeomStaticRigidBody && m_iGeomFacesCount > pShapeInfo->m_triangleIndex)
{
return(m_pGeomMtlTypes[pShapeInfo->m_triangleIndex]);
}
return(mpt_default);
}
//##############################################################
void PhyWorld::DebugDrawer::drawLine(const btVector3 & from, const btVector3 & to, const btVector3 & color)
......
......@@ -12,6 +12,23 @@
#include <gdefines.h>
#include <common/SXMath.h>
#include <mtllight/sxmtllight.h>
#define PHY_MAT_FILE_MAGICK 8386069164979148883
#pragma pack(push,1)
struct PhyMatFile
{
int64_t i64Magick;
uint32_t uiGeomFaceCount;
//uint32_t uiGreenObjCount;
PhyMatFile():
i64Magick(PHY_MAT_FILE_MAGICK)
{
}
};
#pragma pack(pop)
extern report_func reportf;
......@@ -36,6 +53,8 @@ public:
void Render();
MtlPhysicType GetMtlType(const btCollisionObject *pBody, const btCollisionWorld::LocalShapeInfo *pShapeInfo);
btDiscreteDynamicsWorld * GetBtWorld()
{
return(m_pDynamicsWorld);
......@@ -81,7 +100,8 @@ protected:
btTriangleMesh * m_pGeomStaticCollideMesh;
btCollisionShape * m_pGeomStaticCollideShape;
btRigidBody * m_pGeomStaticRigidBody;
int ** m_ppGeomMtlTypes;
MtlPhysicType *m_pGeomMtlTypes;
int m_iGeomFacesCount;
int m_iGeomModelCount;
btCollisionShape ** m_ppGreenStaticCollideShape;
......
......@@ -85,6 +85,8 @@ SX_LIB_API void SXPhysics_AddShape(btRigidBody * pBody);
*/
SX_LIB_API void SXPhysics_RemoveShape(btRigidBody * pBody);
SX_LIB_API int SXPhysics_GetMtlType(const btCollisionObject *pBody, const btCollisionWorld::LocalShapeInfo *pShapeInfo);
SX_LIB_API btDiscreteDynamicsWorld * SXPhysics_GetDynWorld();
#endif
......
......@@ -140,3 +140,10 @@ SX_LIB_API bool SXPhysics_ExportGeom(const char * file)
SP_PRECOND(false);
return(g_pWorld->ExportGeom(file));
}
SX_LIB_API int SXPhysics_GetMtlType(const btCollisionObject *pBody, const btCollisionWorld::LocalShapeInfo *pShapeInfo)
{
SP_PRECOND(mpt_default);
return(g_pWorld->GetMtlType(pBody, pShapeInfo));
}
\ No newline at end of file
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