mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 03:42:48 +01:00
Remove monolithic model list
This commit is contained in:
parent
6951434be8
commit
62ad6b8628
@ -27,11 +27,7 @@ GameData::GameData(Logger* log, WorkContext* work, const std::string& path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameData::~GameData() {
|
GameData::~GameData() {
|
||||||
for (auto& m : models) {
|
/// @todo don't leak models
|
||||||
if (m.second->resource) {
|
|
||||||
delete m.second->resource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameData::load() {
|
void GameData::load() {
|
||||||
@ -45,9 +41,6 @@ void GameData::load() {
|
|||||||
loadLevelFile("data/default.dat");
|
loadLevelFile("data/default.dat");
|
||||||
loadLevelFile("data/gta3.dat");
|
loadLevelFile("data/gta3.dat");
|
||||||
|
|
||||||
loadDFF("wheels.dff");
|
|
||||||
loadDFF("weapons.dff");
|
|
||||||
loadDFF("arrow.dff");
|
|
||||||
loadTXD("particle.txd");
|
loadTXD("particle.txd");
|
||||||
loadTXD("icons.txd");
|
loadTXD("icons.txd");
|
||||||
loadTXD("hud.txd");
|
loadTXD("hud.txd");
|
||||||
@ -313,29 +306,6 @@ void GameData::loadTXD(const std::string& name, bool async) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameData::loadDFF(const std::string& name, bool async) {
|
|
||||||
auto realname = name.substr(0, name.size() - 4);
|
|
||||||
if (models.find(realname) != models.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Before starting the job make sure the file isn't loaded again.
|
|
||||||
loadedFiles.insert({name, true});
|
|
||||||
|
|
||||||
models[realname] = ModelRef(new ResourceHandle<Model>(realname));
|
|
||||||
|
|
||||||
auto job = new BackgroundLoaderJob<Model, LoaderDFF>{
|
|
||||||
workContext, &this->index, name, models[realname]};
|
|
||||||
|
|
||||||
if (async) {
|
|
||||||
workContext->queueJob(job);
|
|
||||||
} else {
|
|
||||||
job->work();
|
|
||||||
job->complete();
|
|
||||||
delete job;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameData::getNameAndLod(std::string& name, int& lod) {
|
void GameData::getNameAndLod(std::string& name, int& lod) {
|
||||||
auto lodpos = name.rfind("_l");
|
auto lodpos = name.rfind("_l");
|
||||||
if (lodpos != std::string::npos) {
|
if (lodpos != std::string::npos) {
|
||||||
|
@ -118,11 +118,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void loadTXD(const std::string& name, bool async = false);
|
void loadTXD(const std::string& name, bool async = false);
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to load a DFF or does nothing if is already loaded
|
|
||||||
*/
|
|
||||||
void loadDFF(const std::string& name, bool async = false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts combined {name}_l{LOD} into name and lod.
|
* Converts combined {name}_l{LOD} into name and lod.
|
||||||
*/
|
*/
|
||||||
@ -229,11 +224,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
WeatherLoader weatherLoader;
|
WeatherLoader weatherLoader;
|
||||||
|
|
||||||
/**
|
|
||||||
* Loaded models
|
|
||||||
*/
|
|
||||||
std::map<std::string, ResourceHandle<Model>::Ref> models;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loaded textures (Textures are ID by name and alpha pairs)
|
* Loaded textures (Textures are ID by name and alpha pairs)
|
||||||
*/
|
*/
|
||||||
|
@ -369,7 +369,8 @@ CharacterObject* GameWorld::createPedestrian(const uint16_t id,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pt->isLoaded()) {
|
auto isSpecial = pt->name.compare(0, 7, "special") == 0;
|
||||||
|
if (!pt->isLoaded() || isSpecial) {
|
||||||
data->loadModel(id);
|
data->loadModel(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,6 +813,7 @@ void GameWorld::loadSpecialCharacter(const unsigned short index,
|
|||||||
std::string lowerName(name);
|
std::string lowerName(name);
|
||||||
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(),
|
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(),
|
||||||
::tolower);
|
::tolower);
|
||||||
|
// Need to replace any existing loaded model
|
||||||
/// @todo a bit more smarter than this
|
/// @todo a bit more smarter than this
|
||||||
state->specialCharacters[index] = lowerName;
|
state->specialCharacters[index] = lowerName;
|
||||||
}
|
}
|
||||||
|
@ -366,11 +366,12 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera& camera,
|
|||||||
|
|
||||||
RW_PROFILE_END();
|
RW_PROFILE_END();
|
||||||
|
|
||||||
|
/// @todo this shouldn't be static here
|
||||||
|
static auto arrowModel = world->data->loadClump("arrow.dff");
|
||||||
// Render arrows above anything that isn't radar only (or hidden)
|
// Render arrows above anything that isn't radar only (or hidden)
|
||||||
ModelRef& arrowModel = world->data->models["arrow"];
|
if (arrowModel) {
|
||||||
if (arrowModel && arrowModel->resource) {
|
|
||||||
auto arrowTex = world->data->textures[{"copblue", ""}];
|
auto arrowTex = world->data->textures[{"copblue", ""}];
|
||||||
auto arrowFrame = arrowModel->resource->findFrame("arrow");
|
auto arrowFrame = arrowModel->findFrame("arrow");
|
||||||
for (auto& blip : world->state->radarBlips) {
|
for (auto& blip : world->state->radarBlips) {
|
||||||
auto dm = blip.second.display;
|
auto dm = blip.second.display;
|
||||||
if (dm == BlipData::Hide || dm == BlipData::RadarOnly) {
|
if (dm == BlipData::Hide || dm == BlipData::RadarOnly) {
|
||||||
@ -399,8 +400,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera& camera,
|
|||||||
dp.ambient = 1.f;
|
dp.ambient = 1.f;
|
||||||
dp.colour = glm::u8vec4(255, 255, 255, 255);
|
dp.colour = glm::u8vec4(255, 255, 255, 255);
|
||||||
|
|
||||||
auto geom = arrowModel->resource
|
auto geom = arrowModel->geometries[arrowFrame->getGeometries()[0]];
|
||||||
->geometries[arrowFrame->getGeometries()[0]];
|
|
||||||
Model::SubGeometry& sg = geom->subgeom[0];
|
Model::SubGeometry& sg = geom->subgeom[0];
|
||||||
|
|
||||||
dp.start = sg.start;
|
dp.start = sg.start;
|
||||||
|
@ -155,26 +155,6 @@ bool ObjectRenderer::renderFrame(Model* m, ModelFrame* f,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectRenderer::renderItem(InventoryItem* item,
|
|
||||||
const glm::mat4& modelMatrix,
|
|
||||||
RenderList& outList) {
|
|
||||||
// srhand
|
|
||||||
if (item->getModelID() == -1) {
|
|
||||||
return; // No model for this item
|
|
||||||
}
|
|
||||||
|
|
||||||
auto odata = m_world->data->modelinfo[item->getModelID()].get();
|
|
||||||
auto weapons = m_world->data->models["weapons"];
|
|
||||||
if (weapons && weapons->resource) {
|
|
||||||
auto itemModel = weapons->resource->findFrame(odata->name + "_l0");
|
|
||||||
auto matrix = glm::inverse(itemModel->getTransform());
|
|
||||||
if (itemModel) {
|
|
||||||
renderFrame(weapons->resource, itemModel, modelMatrix * matrix,
|
|
||||||
nullptr, 1.f, outList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectRenderer::renderInstance(InstanceObject* instance,
|
void ObjectRenderer::renderInstance(InstanceObject* instance,
|
||||||
RenderList& outList) {
|
RenderList& outList) {
|
||||||
if (!instance->getModel()) {
|
if (!instance->getModel()) {
|
||||||
@ -229,8 +209,7 @@ void ObjectRenderer::renderInstance(InstanceObject* instance,
|
|||||||
auto lodmodelinfo =
|
auto lodmodelinfo =
|
||||||
instance->LODinstance->getModelInfo<SimpleModelInfo>();
|
instance->LODinstance->getModelInfo<SimpleModelInfo>();
|
||||||
float LODrange = lodmodelinfo->getLodDistance(0);
|
float LODrange = lodmodelinfo->getLodDistance(0);
|
||||||
if (mindist <= LODrange &&
|
if (mindist <= LODrange && instance->LODinstance->getModel()) {
|
||||||
instance->LODinstance->getModel()) {
|
|
||||||
// The model matrix needs to be for the LOD instead
|
// The model matrix needs to be for the LOD instead
|
||||||
matrixModel =
|
matrixModel =
|
||||||
instance->LODinstance->getTimeAdjustedTransform(
|
instance->LODinstance->getTimeAdjustedTransform(
|
||||||
@ -320,10 +299,16 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
|
|||||||
|
|
||||||
auto root = pedestrian->getModel()->frames[0];
|
auto root = pedestrian->getModel()->frames[0];
|
||||||
|
|
||||||
renderFrame(pedestrian->getModel(), root->getChildren()[0],
|
renderFrame(pedestrian->getModel(), root->getChildren()[0], matrixModel,
|
||||||
matrixModel, pedestrian, 1.f, outList);
|
pedestrian, 1.f, outList);
|
||||||
|
|
||||||
if (pedestrian->getActiveItem()) {
|
if (pedestrian->getActiveItem()) {
|
||||||
|
auto item = pedestrian->getActiveItem();
|
||||||
|
|
||||||
|
if (item->getModelID() == -1) {
|
||||||
|
return; // No model for this item
|
||||||
|
}
|
||||||
|
|
||||||
auto handFrame = pedestrian->getModel()->findFrame("srhand");
|
auto handFrame = pedestrian->getModel()->findFrame("srhand");
|
||||||
glm::mat4 localMatrix;
|
glm::mat4 localMatrix;
|
||||||
if (handFrame) {
|
if (handFrame) {
|
||||||
@ -334,32 +319,13 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
|
|||||||
handFrame = handFrame->getParent();
|
handFrame = handFrame->getParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderItem(pedestrian->getActiveItem(), matrixModel * localMatrix,
|
|
||||||
outList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectRenderer::renderWheel(VehicleObject* vehicle, Model* model,
|
// Assume items are all simple
|
||||||
const glm::mat4& matrix,
|
auto simple =
|
||||||
const std::string& name, RenderList& outList) {
|
m_world->data->findModelInfo<SimpleModelInfo>(item->getModelID());
|
||||||
for (const ModelFrame* f : model->frames) {
|
auto geometry = simple->getAtomic(0)->getGeometries().at(0);
|
||||||
const std::string& fname = f->getName();
|
renderGeometry(simple->getModel(), geometry, matrixModel * localMatrix,
|
||||||
if (fname != name) {
|
1.f, nullptr, outList);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto firstLod = f->getChildren()[0];
|
|
||||||
|
|
||||||
for (auto& g : firstLod->getGeometries()) {
|
|
||||||
RW::BSGeometryBounds& bounds = model->geometries[g]->geometryBounds;
|
|
||||||
if (!m_camera.frustum.intersects(
|
|
||||||
bounds.center + glm::vec3(matrix[3]), bounds.radius)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderGeometry(model, g, matrix, 1.f, vehicle, outList);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,49 +343,48 @@ void ObjectRenderer::renderVehicle(VehicleObject* vehicle,
|
|||||||
matrixModel, vehicle, 1.f, outList);
|
matrixModel, vehicle, 1.f, outList);
|
||||||
|
|
||||||
auto modelinfo = vehicle->getVehicle();
|
auto modelinfo = vehicle->getVehicle();
|
||||||
|
|
||||||
// Draw wheels n' stuff
|
// Draw wheels n' stuff
|
||||||
|
auto woi =
|
||||||
|
m_world->data->findModelInfo<SimpleModelInfo>(modelinfo->wheelmodel_);
|
||||||
|
if (!woi || !woi->isLoaded()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto wheelgeom = woi->getAtomic(0)->getGeometries().at(0);
|
||||||
for (size_t w = 0; w < vehicle->info->wheels.size(); ++w) {
|
for (size_t w = 0; w < vehicle->info->wheels.size(); ++w) {
|
||||||
auto woi = m_world->data->findModelInfo<SimpleModelInfo>(
|
auto& wi = vehicle->physVehicle->getWheelInfo(w);
|
||||||
modelinfo->wheelmodel_);
|
// Construct our own matrix so we can use the local transform
|
||||||
if (woi) {
|
vehicle->physVehicle->updateWheelTransform(w, false);
|
||||||
Model* wheelModel = m_world->data->models["wheels"]->resource;
|
/// @todo migrate this into Vehicle physics tick so we can
|
||||||
auto& wi = vehicle->physVehicle->getWheelInfo(w);
|
/// interpolate old -> new
|
||||||
if (wheelModel) {
|
|
||||||
// Construct our own matrix so we can use the local transform
|
|
||||||
vehicle->physVehicle->updateWheelTransform(w, false);
|
|
||||||
/// @todo migrate this into Vehicle physics tick so we can
|
|
||||||
/// interpolate old -> new
|
|
||||||
|
|
||||||
glm::mat4 wheelM(matrixModel);
|
glm::mat4 wheelM(matrixModel);
|
||||||
|
|
||||||
auto up = -wi.m_wheelDirectionCS;
|
auto up = -wi.m_wheelDirectionCS;
|
||||||
auto right = wi.m_wheelAxleCS;
|
auto right = wi.m_wheelAxleCS;
|
||||||
auto fwd = up.cross(right);
|
auto fwd = up.cross(right);
|
||||||
btQuaternion steerQ(up, wi.m_steering);
|
btQuaternion steerQ(up, wi.m_steering);
|
||||||
btQuaternion rollQ(right, -wi.m_rotation);
|
btQuaternion rollQ(right, -wi.m_rotation);
|
||||||
|
|
||||||
btMatrix3x3 basis(right[0], fwd[0], up[0], right[1], fwd[1],
|
btMatrix3x3 basis(right[0], fwd[0], up[0], right[1], fwd[1], up[1],
|
||||||
up[1], right[2], fwd[2], up[2]);
|
right[2], fwd[2], up[2]);
|
||||||
|
|
||||||
btTransform t;
|
btTransform t;
|
||||||
t.setBasis(btMatrix3x3(steerQ) * btMatrix3x3(rollQ) * basis);
|
t.setBasis(btMatrix3x3(steerQ) * btMatrix3x3(rollQ) * basis);
|
||||||
t.setOrigin(wi.m_chassisConnectionPointCS +
|
t.setOrigin(wi.m_chassisConnectionPointCS +
|
||||||
wi.m_wheelDirectionCS *
|
wi.m_wheelDirectionCS *
|
||||||
wi.m_raycastInfo.m_suspensionLength);
|
wi.m_raycastInfo.m_suspensionLength);
|
||||||
|
|
||||||
t.getOpenGLMatrix(glm::value_ptr(wheelM));
|
t.getOpenGLMatrix(glm::value_ptr(wheelM));
|
||||||
wheelM = matrixModel * wheelM;
|
wheelM = matrixModel * wheelM;
|
||||||
|
|
||||||
wheelM =
|
wheelM = glm::scale(wheelM, glm::vec3(modelinfo->wheelscale_));
|
||||||
glm::scale(wheelM, glm::vec3(modelinfo->wheelscale_));
|
if (wi.m_chassisConnectionPointCS.x() < 0.f) {
|
||||||
if (wi.m_chassisConnectionPointCS.x() < 0.f) {
|
wheelM = glm::scale(wheelM, glm::vec3(-1.f, 1.f, 1.f));
|
||||||
wheelM = glm::scale(wheelM, glm::vec3(-1.f, 1.f, 1.f));
|
|
||||||
}
|
|
||||||
|
|
||||||
renderWheel(vehicle, wheelModel, wheelM, woi->name,
|
|
||||||
outList);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderGeometry(woi->getModel(), wheelgeom, wheelM, 1.f, nullptr,
|
||||||
|
outList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,34 +397,16 @@ void ObjectRenderer::renderPickup(PickupObject* pickup, RenderList& outList) {
|
|||||||
|
|
||||||
auto odata = pickup->getModelInfo<SimpleModelInfo>();
|
auto odata = pickup->getModelInfo<SimpleModelInfo>();
|
||||||
|
|
||||||
Model* model = nullptr;
|
auto model = odata->getModel();
|
||||||
ModelFrame* itemModel = nullptr;
|
auto itemModel = odata->getAtomic(0);
|
||||||
|
auto geom = 0;
|
||||||
/// @todo Better determination of is this object a weapon.
|
if (!itemModel->getGeometries().empty()) {
|
||||||
if (odata->id() >= 170 && odata->id() <= 184) {
|
geom = itemModel->getGeometries()[0];
|
||||||
auto weapons = m_world->data->models["weapons"];
|
} else if (!itemModel->getChildren().empty()) {
|
||||||
if (weapons && weapons->resource && odata) {
|
geom = itemModel->getChildren()[0]->getGeometries()[0];
|
||||||
model = weapons->resource;
|
|
||||||
itemModel = weapons->resource->findFrame(odata->name + "_l0");
|
|
||||||
RW_CHECK(itemModel, "Weapon Frame not present int weapon model");
|
|
||||||
if (!itemModel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto handle = m_world->data->models[odata->name];
|
|
||||||
RW_CHECK(handle && handle->resource, "Pickup has no model");
|
|
||||||
if (handle && handle->resource) {
|
|
||||||
model = handle->resource;
|
|
||||||
itemModel = model->frames[model->rootFrameIdx];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemModel) {
|
renderGeometry(model, geom, modelMatrix, 1.f, pickup, outList);
|
||||||
auto matrix = glm::inverse(itemModel->getTransform());
|
|
||||||
renderFrame(model, itemModel, modelMatrix * matrix, pickup, 1.f,
|
|
||||||
outList);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene,
|
void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene,
|
||||||
@ -511,19 +458,12 @@ void ObjectRenderer::renderProjectile(ProjectileObject* projectile,
|
|||||||
|
|
||||||
auto odata = m_world->data->findModelInfo<SimpleModelInfo>(
|
auto odata = m_world->data->findModelInfo<SimpleModelInfo>(
|
||||||
projectile->getProjectileInfo().weapon->modelID);
|
projectile->getProjectileInfo().weapon->modelID);
|
||||||
auto weapons = m_world->data->models["weapons"];
|
|
||||||
|
|
||||||
RW_CHECK(weapons, "Weapons model not loaded");
|
auto model = odata->getModel();
|
||||||
|
auto modelframe = odata->getAtomic(0);
|
||||||
|
auto geom = modelframe->getGeometries().at(0);
|
||||||
|
|
||||||
if (weapons && weapons->resource) {
|
renderGeometry(model, geom, modelMatrix, 1.f, projectile, outList);
|
||||||
auto itemModel = weapons->resource->findFrame(odata->name + "_l0");
|
|
||||||
auto matrix = glm::inverse(itemModel->getTransform());
|
|
||||||
RW_CHECK(itemModel, "Weapon frame not in model");
|
|
||||||
if (itemModel) {
|
|
||||||
renderFrame(weapons->resource, itemModel, modelMatrix * matrix,
|
|
||||||
projectile, 1.f, outList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList) {
|
void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList) {
|
||||||
|
@ -48,12 +48,6 @@ private:
|
|||||||
void renderCutsceneObject(CutsceneObject* cutscene, RenderList& outList);
|
void renderCutsceneObject(CutsceneObject* cutscene, RenderList& outList);
|
||||||
void renderProjectile(ProjectileObject* projectile, RenderList& outList);
|
void renderProjectile(ProjectileObject* projectile, RenderList& outList);
|
||||||
|
|
||||||
void renderItem(InventoryItem* item, const glm::mat4& modelMatrix,
|
|
||||||
RenderList& outList);
|
|
||||||
void renderWheel(VehicleObject* vehicle, Model* model,
|
|
||||||
const glm::mat4& matrix, const std::string& name,
|
|
||||||
RenderList& outList);
|
|
||||||
|
|
||||||
bool renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
|
bool renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
|
||||||
GameObject* object, float opacity, RenderList& outList);
|
GameObject* object, float opacity, RenderList& outList);
|
||||||
|
|
||||||
|
@ -15,10 +15,9 @@ BOOST_AUTO_TEST_CASE(test_matrix) {
|
|||||||
|
|
||||||
/** Models are currently needed to relate animation bones <=> model
|
/** Models are currently needed to relate animation bones <=> model
|
||||||
* frame #s. */
|
* frame #s. */
|
||||||
Global::get().e->data->loadDFF("player.dff");
|
auto test_model = Global::get().d->loadClump("player.dff");
|
||||||
ModelRef& test_model = Global::get().e->data->models["player"];
|
|
||||||
|
|
||||||
Animator animator(test_model->resource, &skeleton);
|
Animator animator(test_model, &skeleton);
|
||||||
|
|
||||||
animation.duration = 1.f;
|
animation.duration = 1.f;
|
||||||
animation.bones["player"] = new AnimationBone{
|
animation.bones["player"] = new AnimationBone{
|
||||||
|
Loading…
Reference in New Issue
Block a user