Commit d3fa06e6 authored by Martin Turski's avatar Martin Turski

- added a file to put RW helpers in in-case our vendor does not provide them

- improved management of models; they are now set up as atomics or clumps depending on their type
- optimized some math
- disabled some warning in Game.cpp
parent 63501dd2
Pipeline #39 skipped
......@@ -31,4 +31,5 @@
#include <utils/StringConvert.h>
#include <utils/LockUtil.h>
#include <rw.h>
\ No newline at end of file
#include <rw.h>
#include <RwHelpers.h>
\ No newline at end of file
......@@ -15,9 +15,19 @@ namespace krt
// General model information management container.
struct ModelManager : public streaming::StreamingTypeInterface
{
enum class eModelType
{
ATOMIC,
VEHICLE,
PED
};
struct ModelResource
{
inline streaming::ident_t GetID( void ) const { return this->id; }
inline eModelType GetType( void ) const { return this->modelType; }
rw::Object* CloneModel( void );
private:
friend struct ModelManager;
......@@ -32,20 +42,24 @@ struct ModelManager : public streaming::StreamingTypeInterface
return;
}
ModelManager *manager;
streaming::ident_t id;
streaming::ident_t texDictID;
float lodDistance;
int flags;
eModelType modelType;
DeviceResourceLocation vfsResLoc;
rw::Clump *modelPtr;
rw::Object *modelPtr;
};
ModelManager( streaming::StreamMan& streaming, TextureManager& texManager );
~ModelManager( void );
void RegisterResource(
void RegisterAtomicModel(
streaming::ident_t id,
std::string name, std::string texDictName, float lodDistance, int flags,
std::string relFilePath
......@@ -67,6 +81,8 @@ private:
std::vector <ModelResource*> models;
std::map <std::string, ModelResource*> modelByName;
std::shared_timed_mutex lockModelContext;
};
}
\ No newline at end of file
#pragma once
// Common helpers because aap refuses to put good coding practice of C++ into his library.
namespace rw
{
template <typename cbType>
inline void clumpForAllAtomics( rw::Clump *clump, cbType& cb )
{
FORLIST(lnk, clump->atomics)
cb( Atomic::fromClump( lnk ) );
}
template <typename cbType>
inline void clumpForAllLights( rw::Clump *clump, cbType& cb )
{
FORLIST(lnk, clump->lights)
cb( Light::fromClump( lnk ) );
}
template <typename cbType>
inline void clumpForAllCameras( rw::Clump *clump, cbType& cb )
{
FORLIST(lnk, clump->cameras)
cb( Camera::fromClump( lnk ) );
}
};
\ No newline at end of file
......@@ -20,6 +20,9 @@ struct TextureManager : public streaming::StreamingTypeInterface
streaming::ident_t FindTexDict( const std::string& name ) const;
void SetTexParent( const std::string& texName, const std::string& texParentName );
void SetCurrentTXD( streaming::ident_t id );
void UnsetCurrentTXD( void );
void LoadResource( streaming::ident_t localID, const void *data, size_t dataSize ) override;
void UnloadResource( streaming::ident_t localID ) override;
......@@ -53,6 +56,8 @@ private:
std::vector <TexDictResource*> texDictList;
std::map <std::string, TexDictResource*> texDictMap;
mutable std::shared_timed_mutex lockTextureContext;
};
}
\ No newline at end of file
......@@ -13,6 +13,8 @@
#include <src/rwgta.h>
#pragma warning(disable:4996)
namespace krt
{
......@@ -59,7 +61,7 @@ Game::Game( void ) : streaming( GAME_NUM_STREAMING_CHANNELS ), texManager( strea
this->RunCommandFile( "DATA\\GTA.DAT" );
// Do a test that loads all game models.
//modelManager.LoadAllModels();
modelManager.LoadAllModels();
}
Game::~Game( void )
......@@ -389,13 +391,13 @@ void Game::LoadIDEFile( std::string relPath )
streaming::ident_t id = atoi( args[0].c_str() );
const std::string& modelName = args[1];
const std::string& txdName = args[2];
float lodDistance = atof( args[3].c_str() );
double lodDistance = atof( args[3].c_str() );
std::uint32_t flags = atoi( args[4].c_str() );
// TODO: meow, actually implement this.
// need a good resource location idea for this :3
modelManager.RegisterResource( id, modelName, txdName, lodDistance, flags, modelName + ".dff" );
modelManager.RegisterAtomicModel( id, modelName, txdName, (float)lodDistance, flags, modelName + ".dff" );
}
// TODO: is there any different format with less or more arguments?
// maybe for IPL?
......
......@@ -37,7 +37,7 @@ ModelManager::~ModelManager( void )
streaming.UnregisterResourceType( MODEL_ID_BASE );
}
void ModelManager::RegisterResource(
void ModelManager::RegisterAtomicModel(
streaming::ident_t id,
std::string name, std::string texDictName, float lodDistance, int flags,
std::string relFilePath
......@@ -69,11 +69,14 @@ void ModelManager::RegisterResource(
ModelResource *modelEntry = new ModelResource( resDevice, std::move( devPath ) );
modelEntry->manager = this;
modelEntry->id = id;
modelEntry->texDictID = -1;
modelEntry->lodDistance = lodDistance;
modelEntry->flags = flags;
modelEntry->modelPtr = NULL;
modelEntry->modelType = eModelType::ATOMIC;
bool couldLink = streaming.LinkResource( id, name, &modelEntry->vfsResLoc );
......@@ -121,6 +124,8 @@ ModelManager::ModelResource* ModelManager::GetModelByID( streaming::ident_t id )
if ( id < 0 || id >= MAX_MODELS )
return NULL;
shared_lock_acquire <std::shared_timed_mutex> ctxGetModel( this->lockModelContext );
return this->models[ id ];
}
......@@ -139,14 +144,59 @@ void ModelManager::LoadAllModels( void )
streaming.LoadingBarrier();
}
rw::Object* ModelManager::ModelResource::CloneModel( void )
{
exclusive_lock_acquire <std::shared_timed_mutex> ctxCloneModel( this->manager->lockModelContext );
rw::Object *modelItem = this->modelPtr;
if ( modelItem == NULL )
return NULL;
rw::uint8 modelType = modelItem->type;
if ( modelType == rw::Atomic::ID )
{
rw::Atomic *atomic = (rw::Atomic*)modelItem;
return (rw::Object*)atomic->clone();
}
else if ( modelType == rw::Clump::ID )
{
rw::Clump *clump = (rw::Clump*)modelItem;
return (rw::Object*)clump->clone();
}
return NULL;
}
static rw::Atomic* GetFirstClumpAtomic( rw::Clump *clump )
{
rw::Atomic *firstAtom = NULL;
rw::clumpForAllAtomics( clump,
[&]( rw::Atomic *atom )
{
if ( !firstAtom )
{
firstAtom = atom;
}
});
return firstAtom;
}
void ModelManager::LoadResource( streaming::ident_t localID, const void *dataBuf, size_t memSize )
{
exclusive_lock_acquire <std::shared_timed_mutex> ctxLoadModel( this->lockModelContext );
ModelResource *modelEntry = this->models[ localID ];
assert( modelEntry != NULL );
// Load the model resource.
rw::Clump *newClump = NULL;
rw::Object *modelPtr = NULL;
{
rw::StreamMemory memoryStream;
memoryStream.open( (rw::uint8*)dataBuf, (rw::uint32)memSize );
......@@ -158,20 +208,58 @@ void ModelManager::LoadResource( streaming::ident_t localID, const void *dataBuf
throw std::exception( "not a model resource" );
}
newClump = rw::Clump::streamRead( &memoryStream );
rw::Clump *newClump = rw::Clump::streamRead( &memoryStream );
if ( !newClump )
{
throw std::exception( "failed to parse model file" );
}
// Process it so that it is in the model format that we want.
eModelType modelType = modelEntry->modelType;
if ( modelType == eModelType::ATOMIC )
{
// We just store an atomic.
rw::Atomic *firstAtom = GetFirstClumpAtomic( newClump );
if ( firstAtom )
{
rw::Atomic *clonedObject = firstAtom->clone();
if ( clonedObject )
{
modelPtr = (rw::Object*)clonedObject;
}
}
newClump->destroy();
}
else if ( modelType == eModelType::VEHICLE ||
modelType == eModelType::PED )
{
// Just store it as clump.
modelPtr = (rw::Object*)newClump;
}
else
{
assert( 0 );
}
if ( modelPtr == NULL )
{
throw std::exception( "invalid model file" );
}
}
// Store us. :)
modelEntry->modelPtr = newClump;
modelEntry->modelPtr = modelPtr;
}
void ModelManager::UnloadResource( streaming::ident_t localID )
{
exclusive_lock_acquire <std::shared_timed_mutex> ctxUnloadModel( this->lockModelContext );
ModelResource *modelEntry = this->models[ localID ];
assert( modelEntry != NULL );
......@@ -180,7 +268,24 @@ void ModelManager::UnloadResource( streaming::ident_t localID )
{
assert( modelEntry->modelPtr != NULL );
modelEntry->modelPtr->destroy();
rw::uint8 modelType = modelEntry->modelPtr->type;
if ( modelType == rw::Atomic::ID )
{
rw::Atomic *atomic = (rw::Atomic*)modelEntry->modelPtr;
atomic->destroy();
}
else if ( modelType == rw::Clump::ID )
{
rw::Clump *clump = (rw::Clump*)modelEntry->modelPtr;
clump->destroy();
}
else
{
assert( 0 );
}
}
modelEntry->modelPtr = NULL;
......
......@@ -73,6 +73,8 @@ TextureManager::TexDictResource* TextureManager::FindTexDictInternal( const std:
streaming::ident_t TextureManager::FindTexDict( const std::string& name ) const
{
shared_lock_acquire <std::shared_timed_mutex> ctxFindTXD( this->lockTextureContext );
TexDictResource *texRes = FindTexDictInternal( name );
if ( !texRes )
......@@ -85,6 +87,8 @@ streaming::ident_t TextureManager::FindTexDict( const std::string& name ) const
void TextureManager::SetTexParent( const std::string& texName, const std::string& texParentName )
{
shared_lock_acquire <std::shared_timed_mutex> ctxSetParent( this->lockTextureContext );
TexDictResource *texDict = this->FindTexDictInternal( texName );
if ( !texDict )
......@@ -128,6 +132,8 @@ void TextureManager::SetTexParent( const std::string& texName, const std::string
void TextureManager::LoadResource( streaming::ident_t localID, const void *dataBuf, size_t memSize )
{
exclusive_lock_acquire <std::shared_timed_mutex> ctxLoadTXD( this->lockTextureContext );
TexDictResource *texEntry = this->texDictList[ localID ];
// Load the TXD resource.
......@@ -157,6 +163,8 @@ void TextureManager::LoadResource( streaming::ident_t localID, const void *dataB
void TextureManager::UnloadResource( streaming::ident_t localID )
{
exclusive_lock_acquire <std::shared_timed_mutex> ctxUnloadTXD( this->lockTextureContext );
TexDictResource *texEntry = this->texDictList[ localID ];
// Unload the TXD again.
......
......@@ -6,6 +6,16 @@ namespace krt
namespace math
{
inline bool isLinearIndependent( const rw::V3d& one, const rw::V3d& two )
{
rw::Matrix3 testMat;
testMat.right = one;
testMat.up = two;
testMat.at = rw::cross( one, two );
return ( testMat.determinant() != 0 );
}
inline bool verifyPlanePointConfiguration(
const rw::V3d& one, const rw::V3d& two, const rw::V3d& three, const rw::V3d& four
)
......@@ -27,21 +37,16 @@ inline bool verifyPlanePointConfiguration(
return false;
}
#if 0
// verify that we atleast have two dimensions.
bool hasTwoDimms = false;
{
if ( rw::dot( oneVec, twoVec ) == 0 ||
rw::dot( oneVec, threeVec ) == 0 ||
rw::dot( twoVec, threeVec ) == 0 )
if ( isLinearIndependent( oneVec, twoVec ) ||
isLinearIndependent( oneVec, threeVec ) ||
isLinearIndependent( twoVec, threeVec ) )
{
hasTwoDimms = true;
}
}
#else
// Well, I trust the programmer for now.
bool hasTwoDimms = true;
#endif
return hasTwoDimms;
}
......@@ -342,9 +347,9 @@ inline bool intersectSphereWithLine(
double alpha = ( lineDir.x * ( off_lp_sc.x ) + lineDir.y * ( off_lp_sc.y ) + lineDir.z * ( off_lp_sc.z ) ) / lineDirLenSq;
double beta = ( off_lp_sc.x * off_lp_sc.x + off_lp_sc.y * off_lp_sc.y + off_lp_sc.z * off_lp_sc.z ) / lineDirLenSq;
double beta = ( off_lp_sc.x * off_lp_sc.x + off_lp_sc.y * off_lp_sc.y + off_lp_sc.z * off_lp_sc.z );
double modifier = ( radius * radius / lineDirLenSq - beta + alpha * alpha );
double modifier = ( ( radius * radius - beta ) / lineDirLenSq + alpha * alpha );
if ( modifier < 0 )
return false;
......
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