2017-01-03 14:18:06 +00:00
|
|
|
#include "data/Clump.hpp"
|
2014-02-09 03:14:43 +00:00
|
|
|
#include <iostream>
|
2017-01-05 01:26:37 +00:00
|
|
|
#include <queue>
|
2014-02-09 03:14:43 +00:00
|
|
|
|
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
Geometry::Geometry() : flags(0) {
|
2013-09-25 09:05:18 +01:00
|
|
|
}
|
|
|
|
|
2017-01-03 16:21:21 +00:00
|
|
|
Geometry::~Geometry() {
|
rwlib: free Geometry OpenGL buffers
Should fix this memory leak:
==31441== 576 bytes in 4 blocks are possibly lost in loss record 2,109 of 2,723
==31441== at 0x4C30A1E: calloc (vg_replace_malloc.c:711)
==31441== by 0x14F98CEF: ??? (in /usr/lib64/dri/i965_dri.so)
==31441== by 0x14FD8303: ??? (in /usr/lib64/dri/i965_dri.so)
==31441== by 0x14FD8B6F: ??? (in /usr/lib64/dri/i965_dri.so)
==31441== by 0x14BF0C40: ??? (in /usr/lib64/dri/i965_dri.so)
==31441== by 0x14BF0E27: ??? (in /usr/lib64/dri/i965_dri.so)
==31441== by 0x910D28: LoaderDFF::readGeometry(RWBStream const&) (LoaderDFF.cpp:253)
==31441== by 0x9104E2: LoaderDFF::readGeometryList(RWBStream const&) (LoaderDFF.cpp:129)
==31441== by 0x911CED: LoaderDFF::loadFromMemory(std::shared_ptr<FileContentsInfo>) (LoaderDFF.cpp:474)
==31441== by 0x7BE007: GameData::loadModel(unsigned short) (GameData.cpp:474)
==31441== by 0x7E0DD2: GameWorld::createInstance(unsigned short, glm::tvec3<float, (glm::precision)0> const&, glm::tquat<float, (glm::precision)0> const&) (GameWorld.cpp:144)
==31441== by 0x86E0BE: opcode_029b(ScriptArguments const&, int, glm::tvec3<float, (glm::precision)0>, ScriptObjectType<InstanceObject>&) (GTA3ModuleImpl.inl:7234)
==31441==
==31441== 696 bytes in 3 blocks are possibly lost in loss record 2,197 of 2,723
==31441== at 0x4C30A1E: calloc (vg_replace_malloc.c:711)
==31441== by 0x14FD8298: ??? (in /usr/lib64/dri/i965_dri.so)
==31441== by 0x14BEEF21: ??? (in /usr/lib64/dri/i965_dri.so)
==31441== by 0x14BEF057: ??? (in /usr/lib64/dri/i965_dri.so)
==31441== by 0x910CA6: LoaderDFF::readGeometry(RWBStream const&) (LoaderDFF.cpp:248)
==31441== by 0x9104E2: LoaderDFF::readGeometryList(RWBStream const&) (LoaderDFF.cpp:129)
==31441== by 0x911CED: LoaderDFF::loadFromMemory(std::shared_ptr<FileContentsInfo>) (LoaderDFF.cpp:474)
==31441== by 0x7BD346: GameData::loadClump(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (GameData.cpp:394)
==31441== by 0x75914F: RWGame::RWGame(Logger&, int, char**) (RWGame.cpp:54)
==31441== by 0x749175: main (main.cpp:13)
2017-09-13 03:12:24 +02:00
|
|
|
glDeleteBuffers(1, &EBO);
|
2013-09-25 09:05:18 +01:00
|
|
|
}
|
2014-02-09 03:14:43 +00:00
|
|
|
|
2017-01-04 21:08:21 +00:00
|
|
|
ModelFrame::ModelFrame(unsigned int index, glm::mat3 dR, glm::vec3 dT)
|
2016-09-09 21:13:21 +01:00
|
|
|
: index(index)
|
|
|
|
, defaultRotation(dR)
|
|
|
|
, defaultTranslation(dT)
|
2017-01-04 21:08:21 +00:00
|
|
|
, parent_(nullptr) {
|
2016-09-09 21:13:21 +01:00
|
|
|
reset();
|
2014-02-09 03:14:43 +00:00
|
|
|
}
|
|
|
|
|
2016-09-09 21:13:21 +01:00
|
|
|
void ModelFrame::reset() {
|
|
|
|
matrix = glm::translate(glm::mat4(), defaultTranslation) *
|
|
|
|
glm::mat4(defaultRotation);
|
2017-01-04 21:08:21 +00:00
|
|
|
updateHierarchyTransform();
|
2014-02-09 03:14:43 +00:00
|
|
|
}
|
|
|
|
|
2017-01-04 21:08:21 +00:00
|
|
|
void ModelFrame::updateHierarchyTransform() {
|
|
|
|
// Update our own transformation
|
|
|
|
if (parent_) {
|
|
|
|
worldtransform_ = parent_->getWorldTransform() * matrix;
|
|
|
|
} else {
|
|
|
|
worldtransform_ = matrix;
|
|
|
|
}
|
|
|
|
for (const auto& child : children_) {
|
|
|
|
child->updateHierarchyTransform();
|
|
|
|
}
|
2014-06-08 22:40:46 +01:00
|
|
|
}
|
2014-08-04 22:21:01 +01:00
|
|
|
|
2017-01-05 01:26:37 +00:00
|
|
|
void ModelFrame::addChild(ModelFramePtr child) {
|
2017-01-04 21:08:21 +00:00
|
|
|
// Make sure the child is an orphan
|
|
|
|
if (child->getParent()) {
|
|
|
|
auto& other_children = child->getParent()->children_;
|
|
|
|
other_children.erase(
|
|
|
|
std::remove(other_children.begin(), other_children.end(), child),
|
|
|
|
other_children.end());
|
|
|
|
}
|
|
|
|
child->parent_ = this;
|
|
|
|
children_.push_back(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
ModelFrame* ModelFrame::findDescendant(const std::string& name) const {
|
|
|
|
for (const auto& frame : children_) {
|
|
|
|
if (frame->getName() == name) {
|
|
|
|
return frame.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto result = frame->findDescendant(name);
|
|
|
|
if (result) {
|
|
|
|
return result;
|
|
|
|
}
|
2016-09-09 21:13:21 +01:00
|
|
|
}
|
2017-01-04 21:08:21 +00:00
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-01-05 01:26:37 +00:00
|
|
|
ModelFramePtr ModelFrame::cloneHierarchy() const {
|
|
|
|
auto self = std::make_shared<ModelFrame>(getIndex(), getDefaultRotation(),
|
|
|
|
getDefaultTranslation());
|
|
|
|
self->setName(getName());
|
|
|
|
for (const auto& child : getChildren()) {
|
|
|
|
auto childclone = child->cloneHierarchy();
|
|
|
|
self->addChild(childclone);
|
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
AtomicPtr Atomic::clone() const {
|
|
|
|
auto newatomic = std::make_shared<Atomic>();
|
|
|
|
newatomic->setGeometry(getGeometry());
|
|
|
|
newatomic->setFrame(getFrame());
|
|
|
|
newatomic->setFlags(getFlags());
|
|
|
|
return newatomic;
|
|
|
|
}
|
|
|
|
|
2017-01-04 21:08:21 +00:00
|
|
|
ModelFrame* Clump::findFrame(const std::string& name) const {
|
|
|
|
if (rootframe_->getName() == name) {
|
|
|
|
return rootframe_.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
return rootframe_->findDescendant(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
Clump::~Clump() {
|
2014-08-04 22:21:01 +01:00
|
|
|
}
|
2015-04-06 04:06:35 +01:00
|
|
|
|
2017-01-03 14:18:06 +00:00
|
|
|
void Clump::recalculateMetrics() {
|
2016-09-09 21:13:21 +01:00
|
|
|
boundingRadius = std::numeric_limits<float>::min();
|
2017-01-04 21:08:21 +00:00
|
|
|
for (const auto& atomic : atomics_) {
|
|
|
|
const auto& geometry = atomic->getGeometry();
|
|
|
|
if (!geometry) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const auto& bounds = geometry->geometryBounds;
|
2016-09-09 21:13:21 +01:00
|
|
|
boundingRadius = std::max(boundingRadius,
|
|
|
|
glm::length(bounds.center) + bounds.radius);
|
|
|
|
}
|
2015-04-06 04:06:35 +01:00
|
|
|
}
|
2017-01-05 01:26:37 +00:00
|
|
|
|
|
|
|
Clump* Clump::clone() const {
|
|
|
|
// Clone frame hierarchy
|
|
|
|
auto newroot = rootframe_->cloneHierarchy();
|
|
|
|
auto clump = new Clump;
|
|
|
|
clump->setFrame(newroot);
|
|
|
|
|
|
|
|
// This isn't the most optimal implementation, but this code is likely
|
|
|
|
// to be replaced soon.
|
|
|
|
auto find_new_frame = [&](const ModelFramePtr& old) -> ModelFramePtr {
|
|
|
|
std::queue<ModelFramePtr> open;
|
|
|
|
open.push(newroot);
|
|
|
|
while (!open.empty()) {
|
|
|
|
auto frame = open.front();
|
|
|
|
open.pop();
|
|
|
|
if (frame->getIndex() == old->getIndex()) {
|
|
|
|
return frame;
|
|
|
|
}
|
|
|
|
for (const auto& child : frame->getChildren()) {
|
|
|
|
open.push(child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Generate new atomics
|
|
|
|
for (const auto& atomic : getAtomics()) {
|
|
|
|
auto newatomic = atomic->clone();
|
|
|
|
// Replace the original frame with the cloned frame
|
|
|
|
if (atomic->getFrame()) {
|
|
|
|
newatomic->setFrame(find_new_frame(atomic->getFrame()));
|
|
|
|
}
|
|
|
|
clump->addAtomic(newatomic);
|
|
|
|
}
|
|
|
|
|
|
|
|
return clump;
|
|
|
|
}
|