1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-18 16:32:32 +02:00

Remove monolithic model list

This commit is contained in:
Daniel Evans 2016-09-11 21:57:55 +01:00
parent 6951434be8
commit 62ad6b8628
7 changed files with 71 additions and 176 deletions

View File

@ -27,11 +27,7 @@ GameData::GameData(Logger* log, WorkContext* work, const std::string& path)
}
GameData::~GameData() {
for (auto& m : models) {
if (m.second->resource) {
delete m.second->resource;
}
}
/// @todo don't leak models
}
void GameData::load() {
@ -45,9 +41,6 @@ void GameData::load() {
loadLevelFile("data/default.dat");
loadLevelFile("data/gta3.dat");
loadDFF("wheels.dff");
loadDFF("weapons.dff");
loadDFF("arrow.dff");
loadTXD("particle.txd");
loadTXD("icons.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) {
auto lodpos = name.rfind("_l");
if (lodpos != std::string::npos) {

View File

@ -118,11 +118,6 @@ public:
*/
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.
*/
@ -229,11 +224,6 @@ public:
*/
WeatherLoader weatherLoader;
/**
* Loaded models
*/
std::map<std::string, ResourceHandle<Model>::Ref> models;
/**
* Loaded textures (Textures are ID by name and alpha pairs)
*/

View File

@ -369,7 +369,8 @@ CharacterObject* GameWorld::createPedestrian(const uint16_t id,
return nullptr;
}
if (!pt->isLoaded()) {
auto isSpecial = pt->name.compare(0, 7, "special") == 0;
if (!pt->isLoaded() || isSpecial) {
data->loadModel(id);
}
@ -812,6 +813,7 @@ void GameWorld::loadSpecialCharacter(const unsigned short index,
std::string lowerName(name);
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(),
::tolower);
// Need to replace any existing loaded model
/// @todo a bit more smarter than this
state->specialCharacters[index] = lowerName;
}

View File

@ -366,11 +366,12 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera& camera,
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)
ModelRef& arrowModel = world->data->models["arrow"];
if (arrowModel && arrowModel->resource) {
if (arrowModel) {
auto arrowTex = world->data->textures[{"copblue", ""}];
auto arrowFrame = arrowModel->resource->findFrame("arrow");
auto arrowFrame = arrowModel->findFrame("arrow");
for (auto& blip : world->state->radarBlips) {
auto dm = blip.second.display;
if (dm == BlipData::Hide || dm == BlipData::RadarOnly) {
@ -399,8 +400,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera& camera,
dp.ambient = 1.f;
dp.colour = glm::u8vec4(255, 255, 255, 255);
auto geom = arrowModel->resource
->geometries[arrowFrame->getGeometries()[0]];
auto geom = arrowModel->geometries[arrowFrame->getGeometries()[0]];
Model::SubGeometry& sg = geom->subgeom[0];
dp.start = sg.start;

View File

@ -155,26 +155,6 @@ bool ObjectRenderer::renderFrame(Model* m, ModelFrame* f,
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,
RenderList& outList) {
if (!instance->getModel()) {
@ -229,8 +209,7 @@ void ObjectRenderer::renderInstance(InstanceObject* instance,
auto lodmodelinfo =
instance->LODinstance->getModelInfo<SimpleModelInfo>();
float LODrange = lodmodelinfo->getLodDistance(0);
if (mindist <= LODrange &&
instance->LODinstance->getModel()) {
if (mindist <= LODrange && instance->LODinstance->getModel()) {
// The model matrix needs to be for the LOD instead
matrixModel =
instance->LODinstance->getTimeAdjustedTransform(
@ -320,10 +299,16 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
auto root = pedestrian->getModel()->frames[0];
renderFrame(pedestrian->getModel(), root->getChildren()[0],
matrixModel, pedestrian, 1.f, outList);
renderFrame(pedestrian->getModel(), root->getChildren()[0], matrixModel,
pedestrian, 1.f, outList);
if (pedestrian->getActiveItem()) {
auto item = pedestrian->getActiveItem();
if (item->getModelID() == -1) {
return; // No model for this item
}
auto handFrame = pedestrian->getModel()->findFrame("srhand");
glm::mat4 localMatrix;
if (handFrame) {
@ -334,32 +319,13 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
handFrame = handFrame->getParent();
}
}
renderItem(pedestrian->getActiveItem(), matrixModel * localMatrix,
outList);
}
}
void ObjectRenderer::renderWheel(VehicleObject* vehicle, Model* model,
const glm::mat4& matrix,
const std::string& name, RenderList& outList) {
for (const ModelFrame* f : model->frames) {
const std::string& fname = f->getName();
if (fname != name) {
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;
// Assume items are all simple
auto simple =
m_world->data->findModelInfo<SimpleModelInfo>(item->getModelID());
auto geometry = simple->getAtomic(0)->getGeometries().at(0);
renderGeometry(simple->getModel(), geometry, matrixModel * localMatrix,
1.f, nullptr, outList);
}
}
@ -377,49 +343,48 @@ void ObjectRenderer::renderVehicle(VehicleObject* vehicle,
matrixModel, vehicle, 1.f, outList);
auto modelinfo = vehicle->getVehicle();
// 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) {
auto woi = m_world->data->findModelInfo<SimpleModelInfo>(
modelinfo->wheelmodel_);
if (woi) {
Model* wheelModel = m_world->data->models["wheels"]->resource;
auto& wi = vehicle->physVehicle->getWheelInfo(w);
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
auto& wi = vehicle->physVehicle->getWheelInfo(w);
// 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 right = wi.m_wheelAxleCS;
auto fwd = up.cross(right);
btQuaternion steerQ(up, wi.m_steering);
btQuaternion rollQ(right, -wi.m_rotation);
auto up = -wi.m_wheelDirectionCS;
auto right = wi.m_wheelAxleCS;
auto fwd = up.cross(right);
btQuaternion steerQ(up, wi.m_steering);
btQuaternion rollQ(right, -wi.m_rotation);
btMatrix3x3 basis(right[0], fwd[0], up[0], right[1], fwd[1],
up[1], right[2], fwd[2], up[2]);
btMatrix3x3 basis(right[0], fwd[0], up[0], right[1], fwd[1], up[1],
right[2], fwd[2], up[2]);
btTransform t;
t.setBasis(btMatrix3x3(steerQ) * btMatrix3x3(rollQ) * basis);
t.setOrigin(wi.m_chassisConnectionPointCS +
wi.m_wheelDirectionCS *
wi.m_raycastInfo.m_suspensionLength);
btTransform t;
t.setBasis(btMatrix3x3(steerQ) * btMatrix3x3(rollQ) * basis);
t.setOrigin(wi.m_chassisConnectionPointCS +
wi.m_wheelDirectionCS *
wi.m_raycastInfo.m_suspensionLength);
t.getOpenGLMatrix(glm::value_ptr(wheelM));
wheelM = matrixModel * wheelM;
t.getOpenGLMatrix(glm::value_ptr(wheelM));
wheelM = matrixModel * wheelM;
wheelM =
glm::scale(wheelM, glm::vec3(modelinfo->wheelscale_));
if (wi.m_chassisConnectionPointCS.x() < 0.f) {
wheelM = glm::scale(wheelM, glm::vec3(-1.f, 1.f, 1.f));
}
renderWheel(vehicle, wheelModel, wheelM, woi->name,
outList);
}
wheelM = glm::scale(wheelM, glm::vec3(modelinfo->wheelscale_));
if (wi.m_chassisConnectionPointCS.x() < 0.f) {
wheelM = glm::scale(wheelM, glm::vec3(-1.f, 1.f, 1.f));
}
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>();
Model* model = nullptr;
ModelFrame* itemModel = nullptr;
/// @todo Better determination of is this object a weapon.
if (odata->id() >= 170 && odata->id() <= 184) {
auto weapons = m_world->data->models["weapons"];
if (weapons && weapons->resource && odata) {
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];
}
auto model = odata->getModel();
auto itemModel = odata->getAtomic(0);
auto geom = 0;
if (!itemModel->getGeometries().empty()) {
geom = itemModel->getGeometries()[0];
} else if (!itemModel->getChildren().empty()) {
geom = itemModel->getChildren()[0]->getGeometries()[0];
}
if (itemModel) {
auto matrix = glm::inverse(itemModel->getTransform());
renderFrame(model, itemModel, modelMatrix * matrix, pickup, 1.f,
outList);
}
renderGeometry(model, geom, modelMatrix, 1.f, pickup, outList);
}
void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene,
@ -511,19 +458,12 @@ void ObjectRenderer::renderProjectile(ProjectileObject* projectile,
auto odata = m_world->data->findModelInfo<SimpleModelInfo>(
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) {
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);
}
}
renderGeometry(model, geom, modelMatrix, 1.f, projectile, outList);
}
void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList) {

View File

@ -48,12 +48,6 @@ private:
void renderCutsceneObject(CutsceneObject* cutscene, 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,
GameObject* object, float opacity, RenderList& outList);

View File

@ -15,10 +15,9 @@ BOOST_AUTO_TEST_CASE(test_matrix) {
/** Models are currently needed to relate animation bones <=> model
* frame #s. */
Global::get().e->data->loadDFF("player.dff");
ModelRef& test_model = Global::get().e->data->models["player"];
auto test_model = Global::get().d->loadClump("player.dff");
Animator animator(test_model->resource, &skeleton);
Animator animator(test_model, &skeleton);
animation.duration = 1.f;
animation.bones["player"] = new AnimationBone{