mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-22 02:12:45 +01:00
Load objects directly
This commit is contained in:
parent
218ffdf66c
commit
6951434be8
@ -126,6 +126,11 @@ public:
|
||||
atomics_[n] = atomic;
|
||||
}
|
||||
|
||||
/// @todo remove this
|
||||
Model* getModel() const {
|
||||
return model_;
|
||||
}
|
||||
|
||||
ModelFrame* getAtomic(int n) const {
|
||||
return atomics_[n];
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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,
|
||||
|
@ -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()) {
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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())) {
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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});
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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});
|
||||
|
Loading…
Reference in New Issue
Block a user