1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 10:22:52 +01:00

Load objects directly

This commit is contained in:
Daniel Evans 2016-09-11 20:04:07 +01:00
parent 218ffdf66c
commit 6951434be8
25 changed files with 267 additions and 272 deletions

View File

@ -126,6 +126,11 @@ public:
atomics_[n] = atomic;
}
/// @todo remove this
Model* getModel() const {
return model_;
}
ModelFrame* getAtomic(int n) const {
return atomics_[n];
}

View File

@ -344,6 +344,21 @@ void GameData::getNameAndLod(std::string& name, int& lod) {
}
}
Model* GameData::loadClump(const std::string& name) {
auto file = index.openFile(name);
if (!file) {
logger->error("Data", "Failed to load model " + name);
return nullptr;
}
LoaderDFF l;
auto m = l.loadFromMemory(file);
if (!m) {
logger->error("Data", "Error loading model file " + name);
return nullptr;
}
return m;
}
void GameData::loadModelFile(const std::string& name) {
auto file = index.openFilePath(name);
if (!file) {
@ -386,6 +401,8 @@ void GameData::loadModel(ModelID model) {
case ModelDataType::ClumpInfo:
// Re-direct the hier objects to the special object ids
name = engine->state->specialModels[info->id()];
/// @todo remove this from here
loadTXD(name + ".txd");
break;
case ModelDataType::PedInfo:
static const std::string specialPrefix("special");
@ -393,6 +410,8 @@ void GameData::loadModel(ModelID model) {
auto sid = name.substr(specialPrefix.size());
unsigned short specialID = std::atoi(sid.c_str());
name = engine->state->specialCharacters[specialID];
/// @todo remove this from here
loadTXD(name + ".txd");
break;
}
default:

View File

@ -128,6 +128,11 @@ public:
*/
static void getNameAndLod(std::string& name, int& lod);
/**
* Loads an archived model and returns it directly
*/
Model* loadClump(const std::string& name);
/**
* Loads a DFF and associates its atomics with models.
*/

View File

@ -178,18 +178,10 @@ InstanceObject* GameWorld::createInstance(const uint16_t id,
std::transform(std::begin(texturename), std::end(texturename),
std::begin(texturename), tolower);
// Ensure the relevant data is loaded.
if (!modelname.empty()) {
if (modelname != "null") {
data->loadDFF(modelname + ".dff", false);
}
}
if (!texturename.empty()) {
data->loadTXD(texturename + ".txd", true);
}
ModelRef m = data->models[modelname];
// Check for dynamic data.
auto dyit = data->dynamicObjectData.find(oi->name);
std::shared_ptr<DynamicObjectData> dydata;
@ -203,7 +195,7 @@ InstanceObject* GameWorld::createInstance(const uint16_t id,
}
auto instance = new InstanceObject(
this, pos, rot, m, glm::vec3(1.f, 1.f, 1.f), oi, nullptr, dydata);
this, pos, rot, glm::vec3(1.f, 1.f, 1.f), oi, nullptr, dydata);
instancePool.insert(instance);
allObjects.push_back(instance);
@ -257,65 +249,34 @@ CutsceneObject* GameWorld::createCutsceneObject(const uint16_t id,
const glm::vec3& pos,
const glm::quat& rot) {
auto modelinfo = data->modelinfo[id].get();
std::string modelname;
if (!modelinfo) {
return nullptr;
}
auto clumpmodel = static_cast<ClumpModelInfo*>(modelinfo);
std::string texturename;
if (modelinfo) {
/// @todo track if the current cutscene model is loaded
if (true || !modelinfo->isLoaded()) {
data->loadModel(id);
}
modelname = modelinfo->name;
texturename = modelinfo->textureslot;
/// @todo Store loaded models directly
switch (modelinfo->type()) {
case ModelDataType::ClumpInfo:
// Re-direct the hier objects to the special object ids
modelname = state->specialModels[id];
texturename = state->specialModels[id];
break;
case ModelDataType::PedInfo:
static const std::string specialPrefix("special");
if (!modelname.compare(0, specialPrefix.size(),
specialPrefix)) {
auto sid = modelname.substr(specialPrefix.size());
unsigned short specialID = std::atoi(sid.c_str());
modelname = state->specialCharacters[specialID];
texturename = state->specialCharacters[specialID];
break;
}
default:
break;
}
/// @todo track if the current cutscene model is loaded
if (true || !modelinfo->isLoaded()) {
data->loadModel(id);
}
auto model = clumpmodel->getModel();
texturename = modelinfo->textureslot;
if (id == 0) {
auto playerobj = pedestrianPool.find(state->playerObject);
if (playerobj) {
modelname = playerobj->model->name;
model = playerobj->getModel();
}
}
// Ensure the relevant data is loaded.
if (modelname.empty()) {
logger->error(
"World", "Cutscene object " + std::to_string(id) + " has no model");
return nullptr;
}
if (modelname != "null") {
data->loadDFF(modelname + ".dff", false);
}
if (!texturename.empty()) {
data->loadTXD(texturename + ".txd", true);
}
ModelRef m = data->models[modelname];
auto instance = new CutsceneObject(this, pos, rot, m, modelinfo);
auto instance = new CutsceneObject(this, pos, rot, model, modelinfo);
cutscenePool.insert(instance);
allObjects.push_back(instance);
@ -327,83 +288,76 @@ VehicleObject* GameWorld::createVehicle(const uint16_t id, const glm::vec3& pos,
const glm::quat& rot,
GameObjectID gid) {
auto vti = data->findModelInfo<VehicleModelInfo>(id);
if (vti) {
logger->info("World", "Creating Vehicle ID " + std::to_string(id) +
" (" + vti->vehiclename_ + ")");
if (!vti) {
return nullptr;
}
logger->info("World", "Creating Vehicle ID " + std::to_string(id) + " (" +
vti->vehiclename_ + ")");
if (!vti->isLoaded()) {
data->loadModel(id);
}
if (!vti->isLoaded()) {
data->loadModel(id);
}
if (!vti->name.empty()) {
data->loadDFF(vti->name + ".dff");
}
if (!vti->textureslot.empty()) {
data->loadTXD(vti->textureslot + ".txd");
}
if (!vti->textureslot.empty()) {
data->loadTXD(vti->textureslot + ".txd");
}
glm::u8vec3 prim(255), sec(128);
auto palit = data->vehiclePalettes.find(
vti->name); // modelname is conveniently lowercase (usually)
if (palit != data->vehiclePalettes.end() && palit->second.size() > 0) {
std::uniform_int_distribution<int> uniform(
0, palit->second.size() - 1);
int set = uniform(randomEngine);
prim = data->vehicleColours[palit->second[set].first];
sec = data->vehicleColours[palit->second[set].second];
} else {
logger->warning("World",
"No colour palette for vehicle " + vti->name);
}
glm::u8vec3 prim(255), sec(128);
auto palit = data->vehiclePalettes.find(
vti->name); // modelname is conveniently lowercase (usually)
if (palit != data->vehiclePalettes.end() && palit->second.size() > 0) {
std::uniform_int_distribution<int> uniform(0, palit->second.size() - 1);
int set = uniform(randomEngine);
prim = data->vehicleColours[palit->second[set].first];
sec = data->vehicleColours[palit->second[set].second];
} else {
logger->warning("World", "No colour palette for vehicle " + vti->name);
}
ModelRef& m = data->models[vti->name];
auto model = m->resource;
auto info = data->vehicleInfo.find(vti->handling_);
if (model && info != data->vehicleInfo.end()) {
if (info->second->wheels.size() == 0 &&
info->second->seats.size() == 0) {
for (const ModelFrame* f : model->frames) {
const std::string& name = f->getName();
auto model = vti->getModel();
auto info = data->vehicleInfo.find(vti->handling_);
if (model && info != data->vehicleInfo.end()) {
if (info->second->wheels.size() == 0 &&
info->second->seats.size() == 0) {
for (const ModelFrame* f : model->frames) {
const std::string& name = f->getName();
if (name.size() > 5 && name.substr(0, 5) == "wheel") {
auto frameTrans = f->getMatrix();
info->second->wheels.push_back(
{glm::vec3(frameTrans[3])});
}
if (name == "ped_frontseat") {
auto p = f->getDefaultTranslation();
// Left seat
p.x = -p.x;
info->second->seats.front.push_back({p});
// Right seat
p.x = -p.x;
info->second->seats.front.push_back({p});
}
if (name == "ped_backseat") {
// @todo how does this work for the barracks, ambulance
// or coach?
auto p = f->getDefaultTranslation();
// Left seat
p.x = -p.x;
info->second->seats.back.push_back({p});
// Right seat
p.x = -p.x;
info->second->seats.back.push_back({p});
}
if (name.size() > 5 && name.substr(0, 5) == "wheel") {
auto frameTrans = f->getMatrix();
info->second->wheels.push_back({glm::vec3(frameTrans[3])});
}
if (name == "ped_frontseat") {
auto p = f->getDefaultTranslation();
// Left seat
p.x = -p.x;
info->second->seats.front.push_back({p});
// Right seat
p.x = -p.x;
info->second->seats.front.push_back({p});
}
if (name == "ped_backseat") {
// @todo how does this work for the barracks, ambulance
// or coach?
auto p = f->getDefaultTranslation();
// Left seat
p.x = -p.x;
info->second->seats.back.push_back({p});
// Right seat
p.x = -p.x;
info->second->seats.back.push_back({p});
}
}
}
auto vehicle =
new VehicleObject{this, pos, rot, m, vti, info->second, prim, sec};
vehicle->setGameObjectID(gid);
vehiclePool.insert(vehicle);
allObjects.push_back(vehicle);
return vehicle;
}
return nullptr;
auto vehicle =
new VehicleObject{this, pos, rot, vti, info->second, prim, sec};
vehicle->setGameObjectID(gid);
vehiclePool.insert(vehicle);
allObjects.push_back(vehicle);
return vehicle;
}
CharacterObject* GameWorld::createPedestrian(const uint16_t id,
@ -411,46 +365,26 @@ CharacterObject* GameWorld::createPedestrian(const uint16_t id,
const glm::quat& rot,
GameObjectID gid) {
auto pt = data->findModelInfo<PedModelInfo>(id);
if (pt) {
if (!pt->isLoaded()) {
data->loadModel(id);
}
std::string modelname = pt->name;
std::string texturename = pt->textureslot;
// Ensure the relevant data is loaded.
if (!modelname.empty()) {
// Some model names have special meanings.
/// @todo Should CharacterObjects handle this?
static std::string specialPrefix("special");
if (!modelname.compare(0, specialPrefix.size(), specialPrefix)) {
auto sid = modelname.substr(specialPrefix.size());
unsigned short specialID = std::atoi(sid.c_str());
modelname = state->specialCharacters[specialID];
texturename = state->specialCharacters[specialID];
}
if (modelname != "null") {
data->loadDFF(modelname + ".dff");
}
}
if (!texturename.empty()) {
data->loadTXD(texturename + ".txd");
}
ModelRef m = data->models[modelname];
if (m && m->resource) {
auto ped = new CharacterObject(this, pos, rot, m, pt);
ped->setGameObjectID(gid);
new DefaultAIController(ped);
pedestrianPool.insert(ped);
allObjects.push_back(ped);
return ped;
}
if (!pt) {
return nullptr;
}
return nullptr;
if (!pt->isLoaded()) {
data->loadModel(id);
}
std::string texturename = pt->textureslot;
if (!texturename.empty()) {
data->loadTXD(texturename + ".txd");
}
auto ped = new CharacterObject(this, pos, rot, pt);
ped->setGameObjectID(gid);
new DefaultAIController(ped);
pedestrianPool.insert(ped);
allObjects.push_back(ped);
return ped;
}
CharacterObject* GameWorld::createPlayer(const glm::vec3& pos,
@ -458,28 +392,28 @@ CharacterObject* GameWorld::createPlayer(const glm::vec3& pos,
GameObjectID gid) {
// Player object ID is hardcoded to 0.
auto pt = data->findModelInfo<PedModelInfo>(0);
if (pt) {
// Model name is also hardcoded.
std::string modelname = "player";
std::string texturename = "player";
// Ensure the relevant data is loaded.
data->loadDFF(modelname + ".dff");
data->loadTXD(texturename + ".txd");
ModelRef m = data->models[modelname];
if (m && m->resource) {
auto ped = new CharacterObject(this, pos, rot, m, nullptr);
ped->setGameObjectID(gid);
ped->setLifetime(GameObject::PlayerLifetime);
players.push_back(new PlayerController(ped));
pedestrianPool.insert(ped);
allObjects.push_back(ped);
return ped;
}
if (!pt) {
return nullptr;
}
return nullptr;
// Model name is also hardcoded.
std::string modelname = "player";
std::string texturename = "player";
if (!pt->isLoaded()) {
auto model = data->loadClump(modelname + ".dff");
pt->setModel(model);
}
data->loadTXD(texturename + ".txd");
auto ped = new CharacterObject(this, pos, rot, pt);
ped->setGameObjectID(gid);
ped->setLifetime(GameObject::PlayerLifetime);
players.push_back(new PlayerController(ped));
pedestrianPool.insert(ped);
allObjects.push_back(ped);
return ped;
}
PickupObject* GameWorld::createPickup(const glm::vec3& pos, int id, int type) {
@ -490,11 +424,10 @@ PickupObject* GameWorld::createPickup(const glm::vec3& pos, int id, int type) {
return nullptr;
}
if (! modelInfo->isLoaded()) {
if (!modelInfo->isLoaded()) {
data->loadModel(id);
}
data->loadDFF(modelInfo->name + ".dff");
data->loadTXD(modelInfo->textureslot + ".txd");
PickupObject* pickup = nullptr;
@ -881,7 +814,6 @@ void GameWorld::loadSpecialCharacter(const unsigned short index,
::tolower);
/// @todo a bit more smarter than this
state->specialCharacters[index] = lowerName;
data->loadDFF(lowerName + ".dff");
}
void GameWorld::loadSpecialModel(const unsigned short index,

View File

@ -9,7 +9,7 @@
#include <objects/ProjectileObject.hpp>
void WeaponItem::fireHitscan(CharacterObject* owner) {
auto handFrame = owner->model->resource->findFrame("srhand");
auto handFrame = owner->getModel()->findFrame("srhand");
glm::mat4 handMatrix;
if (handFrame) {
while (handFrame->getParent()) {

View File

@ -14,9 +14,9 @@ static glm::vec3 enter_offset(0.81756252f, 0.34800607f, -0.486281008f);
const float CharacterObject::DefaultJumpSpeed = 2.f;
CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model,
const glm::quat& rot,
BaseModelInfo *modelinfo)
: GameObject(engine, pos, rot, modelinfo, model)
: GameObject(engine, pos, rot, modelinfo)
, currentState({})
, currentVehicle(nullptr)
, currentSeat(0)
@ -65,9 +65,11 @@ CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos,
animations.kd_front = engine->data->animations["kd_front"];
animations.ko_shot_front = engine->data->animations["ko_shot_front"];
if (model) {
auto info = getModelInfo<PedModelInfo>();
if (info->getModel()) {
setModel(info->getModel());
skeleton = new Skeleton;
animator = new Animator(model->resource, skeleton);
animator = new Animator(getModel(), skeleton);
createActor();
}
@ -86,7 +88,7 @@ void CharacterObject::createActor(const glm::vec2& size) {
}
// Don't create anything without a valid model.
if (model) {
if (getModel()) {
btTransform tf;
tf.setIdentity();
tf.setOrigin(btVector3(position.x, position.y, position.z));
@ -204,8 +206,8 @@ glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
// If we have to, interrogate the movement animation
if (movementAnimation != animations.idle) {
if (!model->resource->frames[0]->getChildren().empty()) {
ModelFrame* root = model->resource->frames[0]->getChildren()[0];
if (!getModel()->frames[0]->getChildren().empty()) {
ModelFrame* root = getModel()->frames[0]->getChildren()[0];
auto it = movementAnimation->bones.find(root->getName());
if (it != movementAnimation->bones.end()) {
AnimationBone* rootBone = it->second;
@ -265,22 +267,20 @@ void CharacterObject::changeCharacterModel(const std::string& name) {
std::transform(modelName.begin(), modelName.end(), modelName.begin(),
::tolower);
engine->data->loadDFF(modelName + ".dff");
engine->data->loadTXD(modelName + ".txd");
/// @todo don't model leak here
auto& models = engine->data->models;
auto mfind = models.find(modelName);
if (mfind != models.end()) {
model = mfind->second;
}
engine->data->loadTXD(modelName + ".txd");
auto newmodel = engine->data->loadClump(modelName + ".dff");
if (skeleton) {
delete animator;
delete skeleton;
}
setModel(newmodel);
skeleton = new Skeleton;
animator = new Animator(model->resource, skeleton);
animator = new Animator(getModel(), skeleton);
}
void CharacterObject::updateCharacter(float dt) {

View File

@ -140,8 +140,7 @@ public:
* @param ped PEDS_t struct to use.
*/
CharacterObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model,
BaseModelInfo* modelinfo);
const glm::quat& rot, BaseModelInfo* modelinfo);
~CharacterObject();
@ -149,7 +148,6 @@ public:
return Character;
}
void tick(float dt);
const CharacterState& getCurrentState() const {

View File

@ -3,13 +3,19 @@
#include <objects/CutsceneObject.hpp>
CutsceneObject::CutsceneObject(GameWorld *engine, const glm::vec3 &pos,
const glm::quat &rot,
const ModelRef &model, BaseModelInfo *modelinfo)
: GameObject(engine, pos, rot, modelinfo, model)
const glm::quat &rot, Model *model,
BaseModelInfo *modelinfo)
: GameObject(engine, pos, rot, modelinfo)
, _parent(nullptr)
, _bone(nullptr) {
if (model) {
setModel(model);
}
else {
setModel(getModelInfo<ClumpModelInfo>()->getModel());
}
skeleton = new Skeleton;
animator = new Animator(model->resource, skeleton);
animator = new Animator(getModel(), skeleton);
}
CutsceneObject::~CutsceneObject() {

View File

@ -12,7 +12,8 @@ class CutsceneObject : public GameObject {
public:
CutsceneObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model, BaseModelInfo *modelinfo);
const glm::quat& rot, Model* model,
BaseModelInfo* modelinfo);
~CutsceneObject();
Type type() {

View File

@ -30,13 +30,20 @@ class GameObject {
BaseModelInfo* modelinfo_;
/**
* Model used for rendering
*/
Model* model_;
protected:
void changeModelInfo(BaseModelInfo* next) {
modelinfo_ = next;
}
public:
glm::vec3 position;
glm::quat rotation;
/// Reference to Model data
ModelRef model;
GameWorld* engine;
Animator* animator; /// Object's animator.
@ -55,14 +62,14 @@ public:
bool visible;
GameObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot,
BaseModelInfo* modelinfo, ModelRef model)
BaseModelInfo* modelinfo)
: _lastPosition(pos)
, _lastRotation(rot)
, objectID(0)
, modelinfo_(modelinfo)
, model_(nullptr)
, position(pos)
, rotation(rot)
, model(model)
, engine(engine)
, animator(nullptr)
, skeleton(nullptr)
@ -96,6 +103,20 @@ public:
return static_cast<T*>(modelinfo_);
}
/**
* @return The model used in rendering
*/
Model* getModel() const {
return model_;
}
/**
* Changes the current model, used for re-dressing chars
*/
void setModel(Model* model) {
model_ = model;
}
/**
* @brief Enumeration of possible object types.
*/

View File

@ -6,12 +6,10 @@
#include <objects/InstanceObject.hpp>
InstanceObject::InstanceObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model,
const glm::vec3& scale,
BaseModelInfo *modelinfo,
InstanceObject* lod,
const glm::quat& rot, const glm::vec3& scale,
BaseModelInfo* modelinfo, InstanceObject* lod,
std::shared_ptr<DynamicObjectData> dyn)
: GameObject(engine, pos, rot, modelinfo, model)
: GameObject(engine, pos, rot, modelinfo)
, health(100.f)
, scale(scale)
, body(nullptr)
@ -123,15 +121,21 @@ void InstanceObject::tick(float dt) {
if (animator) animator->tick(dt);
}
void InstanceObject::changeModel(BaseModelInfo *incoming) {
void InstanceObject::changeModel(BaseModelInfo* incoming) {
if (body) {
delete body;
body = nullptr;
}
/// @todo store the new object
if (incoming) {
if (!incoming->isLoaded()) {
engine->data->loadModel(incoming->id());
}
changeModelInfo(incoming);
/// @todo this should only be temporary
setModel(getModelInfo<SimpleModelInfo>()->getModel());
auto bod = new CollisionInstance;
if (bod->createPhysicsBody(this, incoming->name, dynamics.get())) {

View File

@ -22,9 +22,9 @@ public:
bool _enablePhysics;
InstanceObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model,
const glm::vec3& scale, BaseModelInfo* modelinfo,
InstanceObject* lod, std::shared_ptr<DynamicObjectData> dyn);
const glm::quat& rot, const glm::vec3& scale,
BaseModelInfo* modelinfo, InstanceObject* lod,
std::shared_ptr<DynamicObjectData> dyn);
~InstanceObject();
Type type() {

View File

@ -60,7 +60,7 @@ uint32_t PickupObject::behaviourFlags(PickupType type) {
PickupObject::PickupObject(GameWorld* world, const glm::vec3& position,
BaseModelInfo* modelinfo, PickupType type)
: GameObject(world, position, glm::quat(), modelinfo, nullptr)
: GameObject(world, position, glm::quat(), modelinfo)
, m_ghost(nullptr)
, m_shape(nullptr)
, m_enabled(false)

View File

@ -107,7 +107,7 @@ void ProjectileObject::cleanup() {
ProjectileObject::ProjectileObject(GameWorld* world, const glm::vec3& position,
const ProjectileObject::ProjectileInfo& info)
: GameObject(world, position, glm::quat(), nullptr, nullptr)
: GameObject(world, position, glm::quat(), nullptr)
, _info(info)
, _body(nullptr)
, _ghostBody(nullptr)

View File

@ -83,10 +83,10 @@ private:
};
VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model,
BaseModelInfo *modelinfo, VehicleInfoHandle info,
const glm::u8vec3& prim, const glm::u8vec3& sec)
: GameObject(engine, pos, rot, modelinfo, model)
const glm::quat& rot, BaseModelInfo* modelinfo,
VehicleInfoHandle info, const glm::u8vec3& prim,
const glm::u8vec3& sec)
: GameObject(engine, pos, rot, modelinfo)
, steerAngle(0.f)
, throttle(0.f)
, brake(0.f)
@ -152,7 +152,9 @@ VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos,
// Hide all LOD and damage frames.
skeleton = new Skeleton;
for (ModelFrame* frame : model->resource->frames) {
setModel(getVehicle()->getModel());
for (ModelFrame* frame : getModel()->frames) {
auto& name = frame->getName();
bool isDam = name.find("_dam") != name.npos;
bool isLod = name.find("lo") != name.npos;
@ -554,7 +556,7 @@ bool VehicleObject::takeDamage(const GameObject::DamageInfo& dmg) {
if (skeleton->getData(p->normal->getIndex()).enabled) {
auto& geom =
model->resource->geometries[p->normal->getGeometries()[0]];
getModel()->geometries[p->normal->getGeometries()[0]];
auto pp =
p->normal->getMatrix() * glm::vec4(0.f, 0.f, 0.f, 1.f);
float td = glm::distance(
@ -678,7 +680,7 @@ void VehicleObject::createObjectHinge(Part* part) {
if (okframe->getGeometries().size() == 0) return;
auto& geom = model->resource->geometries[okframe->getGeometries()[0]];
auto& geom = getModel()->geometries[okframe->getGeometries()[0]];
auto gbounds = geom->geometryBounds;
if (fn.find("door") != fn.npos) {

View File

@ -49,9 +49,8 @@ public:
std::map<std::string, Part> dynamicParts;
VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot,
const ModelRef& model, BaseModelInfo* modelinfo,
VehicleInfoHandle info, const glm::u8vec3& prim,
const glm::u8vec3& sec);
BaseModelInfo* modelinfo, VehicleInfoHandle info,
const glm::u8vec3& prim, const glm::u8vec3& sec);
virtual ~VehicleObject();

View File

@ -177,7 +177,7 @@ void ObjectRenderer::renderItem(InventoryItem* item,
void ObjectRenderer::renderInstance(InstanceObject* instance,
RenderList& outList) {
if (!instance->model->resource) {
if (!instance->getModel()) {
return;
}
@ -203,7 +203,7 @@ void ObjectRenderer::renderInstance(InstanceObject* instance,
auto matrixModel = instance->getTimeAdjustedTransform(m_renderAlpha);
float mindist = glm::length(instance->getPosition() - m_camera.position) -
instance->model->resource->getBoundingRadius();
instance->getModel()->getBoundingRadius();
mindist *= 1.f / kDrawDistanceFactor;
Model* model = nullptr;
@ -230,7 +230,7 @@ void ObjectRenderer::renderInstance(InstanceObject* instance,
instance->LODinstance->getModelInfo<SimpleModelInfo>();
float LODrange = lodmodelinfo->getLodDistance(0);
if (mindist <= LODrange &&
instance->LODinstance->model->resource) {
instance->LODinstance->getModel()) {
// The model matrix needs to be for the LOD instead
matrixModel =
instance->LODinstance->getTimeAdjustedTransform(
@ -238,27 +238,27 @@ void ObjectRenderer::renderInstance(InstanceObject* instance,
// If the object is only just out of range, keep
// rendering it and screen-door the LOD.
if (overlap < fadeRange) {
model = instance->LODinstance->model->resource;
fadingModel = instance->model->resource;
model = instance->LODinstance->getModel();
fadingModel = instance->getModel();
opacity = 1.f - (overlap / fadeRange);
} else {
model = instance->LODinstance->model->resource;
model = instance->LODinstance->getModel();
}
}
}
// We don't have a LOD object, so fade out gracefully.
else if (overlap < fadeRange) {
fadingModel = instance->model->resource;
fadingModel = instance->getModel();
opacity = 1.f - (overlap / fadeRange);
}
}
// Otherwise, if we aren't marked as a LOD model, we can render
else if (!modelinfo->LOD) {
model = instance->model->resource;
model = instance->getModel();
}
} else {
auto root = instance->model->resource->frames[0];
auto objectModel = instance->model->resource;
auto root = instance->getModel()->frames[0];
auto objectModel = instance->getModel();
fadingFrame = nullptr;
fadingModel = nullptr;
@ -316,15 +316,15 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
matrixModel = pedestrian->getTimeAdjustedTransform(m_renderAlpha);
}
if (!pedestrian->model->resource) return;
if (!pedestrian->getModel()) return;
auto root = pedestrian->model->resource->frames[0];
auto root = pedestrian->getModel()->frames[0];
renderFrame(pedestrian->model->resource, root->getChildren()[0],
renderFrame(pedestrian->getModel(), root->getChildren()[0],
matrixModel, pedestrian, 1.f, outList);
if (pedestrian->getActiveItem()) {
auto handFrame = pedestrian->model->resource->findFrame("srhand");
auto handFrame = pedestrian->getModel()->findFrame("srhand");
glm::mat4 localMatrix;
if (handFrame) {
while (handFrame->getParent()) {
@ -365,15 +365,15 @@ void ObjectRenderer::renderWheel(VehicleObject* vehicle, Model* model,
void ObjectRenderer::renderVehicle(VehicleObject* vehicle,
RenderList& outList) {
RW_CHECK(vehicle->model, "Vehicle model is null");
RW_CHECK(vehicle->getModel(), "Vehicle model is null");
if (!vehicle->model) {
if (!vehicle->getModel()) {
return;
}
glm::mat4 matrixModel = vehicle->getTimeAdjustedTransform(m_renderAlpha);
renderFrame(vehicle->model->resource, vehicle->model->resource->frames[0],
renderFrame(vehicle->getModel(), vehicle->getModel()->frames[0],
matrixModel, vehicle, 1.f, outList);
auto modelinfo = vehicle->getVehicle();
@ -466,7 +466,7 @@ void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene,
RenderList& outList) {
if (!m_world->state->currentCutscene) return;
if (!cutscene->model->resource) {
if (!cutscene->getModel()) {
return;
}
@ -492,7 +492,7 @@ void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene,
matrixModel = glm::translate(matrixModel, cutsceneOffset);
}
auto model = cutscene->model->resource;
auto model = cutscene->getModel();
if (cutscene->getParentActor()) {
glm::mat4 align;
/// @todo figure out where this 90 degree offset is coming from.

View File

@ -35,8 +35,7 @@ inline bool isInModel(const ScriptArguments& args, CharacterObject* character,
if (data) {
auto vehicle = getCharacterVehicle(character);
if (vehicle) {
return vehicle->model ? vehicle->model->name == data->name
: false;
return vehicle->getVehicle()->id() == model;
}
}
return false;

View File

@ -6836,12 +6836,18 @@ void opcode_023c(const ScriptArguments& args, const ScriptInt arg1, const Script
@arg arg1
*/
bool opcode_023d(const ScriptArguments& args, const ScriptInt arg1) {
/// @todo re-implement this when streaming is added
return true;
RW_UNUSED(args);
RW_UNUSED(arg1);
#if 0
auto model = args.getState()->specialCharacters[arg1];
auto modelfind = args.getWorld()->data->models.find(model);
if( modelfind != args.getWorld()->data->models.end() && modelfind->second->resource != nullptr ) {
return true;
}
return false;
#endif
}
/**
@ -8455,7 +8461,7 @@ void opcode_02f4(const ScriptArguments& args, const ScriptObject object0, const
auto actor = args.getObject<CutsceneObject>(0);
CutsceneObject* object = args.getWorld()->createCutsceneObject(id, args.getWorld()->state->currentCutscene->meta.sceneOffset );
auto headframe = actor->model->resource->findFrame("shead");
auto headframe = actor->getModel()->findFrame("shead");
actor->skeleton->setEnabled(headframe, false);
object->setParentActor(actor, headframe);
@ -11346,17 +11352,14 @@ void opcode_03b6(const ScriptArguments& args, ScriptVec3 coord, const ScriptFloa
auto newobjectid = args.getWorld()->data->findModelObject(newmodel);
auto nobj = args.getWorld()->data->findModelInfo<SimpleModelInfo>(newobjectid);
/// @todo Objects need to adopt the new object ID, not just the model.
for(auto p : args.getWorld()->instancePool.objects) {
auto o = p.second;
if( !o->model ) continue;
if( o->model->name != oldmodel ) continue;
if( !o->getModel() ) continue;
if( o->getModelInfo<BaseModelInfo>()->name != oldmodel ) continue;
float d = glm::distance(coord, o->getPosition());
if( d < radius ) {
args.getWorld()->data->loadDFF(newmodel + ".dff", false);
InstanceObject* inst = static_cast<InstanceObject*>(o);
inst->changeModel(nobj);
inst->model = args.getWorld()->data->models[newmodel];
}
}
}

View File

@ -201,7 +201,8 @@ Menu* DebugState::createMapMenu() {
for (auto& i : gw->instancePool.objects) {
auto obj = static_cast<InstanceObject*>(i.second);
if (std::find(garageDoorModels.begin(), garageDoorModels.end(),
obj->model->name) != garageDoorModels.end()) {
obj->getModelInfo<BaseModelInfo>()->name) !=
garageDoorModels.end()) {
obj->setSolid(false);
}
}

View File

@ -238,9 +238,9 @@ void IngameState::tick(float dt) {
? static_cast<CharacterObject*>(target)->getCurrentVehicle()
: nullptr;
if (vehicle) {
auto model = vehicle->model;
auto model = vehicle->getModel();
float maxDist = 0.f;
for (auto& g : model->resource->geometries) {
for (auto& g : model->geometries) {
float partSize = glm::length(g->geometryBounds.center) +
g->geometryBounds.radius;
maxDist = std::max(partSize, maxDist);

View File

@ -194,7 +194,7 @@ void ViewerWidget::showObject(qint16 item) {
RW_CHECK(dummyObject != nullptr, "Dummy Object is null");
if (dummyObject != nullptr) {
activeModel = dummyObject->model->resource;
activeModel = dummyObject->getModel();
}
}
}

View File

@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(test_activities) {
VehicleObject* vehicle = Global::get().e->createVehicle(
90u, glm::vec3(10.f, 0.f, 0.f), glm::quat());
BOOST_REQUIRE(vehicle != nullptr);
BOOST_REQUIRE(vehicle->model != nullptr);
BOOST_REQUIRE(vehicle->getModel() != nullptr);
auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f});

View File

@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(vehicle_parts) {
Global::get().e->createVehicle(90u, glm::vec3(), glm::quat());
BOOST_REQUIRE(vehicle != nullptr);
BOOST_REQUIRE(vehicle->model != nullptr);
BOOST_REQUIRE(vehicle->getModel() != nullptr);
VehicleObject::Part* part = vehicle->getPart("bonnet_dummy");
@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(vehicle_part_vis) {
Global::get().e->createVehicle(90u, glm::vec3(), glm::quat());
BOOST_REQUIRE(vehicle != nullptr);
BOOST_REQUIRE(vehicle->model != nullptr);
BOOST_REQUIRE(vehicle->getModel() != nullptr);
VehicleObject::Part* bonnetpart = vehicle->getPart("bonnet_dummy");
auto skel = vehicle->skeleton;

View File

@ -12,7 +12,7 @@ BOOST_AUTO_TEST_CASE(TestWeaponScan) {
// Test RADIUS scan
auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f});
BOOST_REQUIRE(character != nullptr);
BOOST_REQUIRE(character->model != nullptr);
BOOST_REQUIRE(character->getModel() != nullptr);
BOOST_REQUIRE(character->physObject != nullptr);
WeaponScan scan(10.f, {0.f, 0.f, 10.f}, {0.f, 0.f, -10.f});