- re-enable rendering wmo doodads
- clean up objects extents functions
This commit is contained in:
@@ -821,13 +821,13 @@ void MapTile::saveTile(World* world)
|
|||||||
lMODF_Data[lID].rot[1] = object->dir.y;
|
lMODF_Data[lID].rot[1] = object->dir.y;
|
||||||
lMODF_Data[lID].rot[2] = object->dir.z;
|
lMODF_Data[lID].rot[2] = object->dir.z;
|
||||||
|
|
||||||
lMODF_Data[lID].extents[0][0] = object->extents[0].x;
|
lMODF_Data[lID].extents[0][0] = object->getExtents()[0].x;
|
||||||
lMODF_Data[lID].extents[0][1] = object->extents[0].y;
|
lMODF_Data[lID].extents[0][1] = object->getExtents()[0].y;
|
||||||
lMODF_Data[lID].extents[0][2] = object->extents[0].z;
|
lMODF_Data[lID].extents[0][2] = object->getExtents()[0].z;
|
||||||
|
|
||||||
lMODF_Data[lID].extents[1][0] = object->extents[1].x;
|
lMODF_Data[lID].extents[1][0] = object->getExtents()[1].x;
|
||||||
lMODF_Data[lID].extents[1][1] = object->extents[1].y;
|
lMODF_Data[lID].extents[1][1] = object->getExtents()[1].y;
|
||||||
lMODF_Data[lID].extents[1][2] = object->extents[1].z;
|
lMODF_Data[lID].extents[1][2] = object->getExtents()[1].z;
|
||||||
|
|
||||||
lMODF_Data[lID].flags = object->mFlags;
|
lMODF_Data[lID].flags = object->mFlags;
|
||||||
lMODF_Data[lID].doodadSet = object->doodadset();
|
lMODF_Data[lID].doodadSet = object->doodadset();
|
||||||
@@ -996,13 +996,13 @@ void MapTile::add_model(uint32_t uid)
|
|||||||
{
|
{
|
||||||
instance->ensureExtents();
|
instance->ensureExtents();
|
||||||
|
|
||||||
_object_instance_extents[0].x = std::min(_object_instance_extents[0].x, instance->extents[0].x);
|
_object_instance_extents[0].x = std::min(_object_instance_extents[0].x, instance->getExtents()[0].x);
|
||||||
_object_instance_extents[0].y = std::min(_object_instance_extents[0].y, instance->extents[0].y);
|
_object_instance_extents[0].y = std::min(_object_instance_extents[0].y, instance->getExtents()[0].y);
|
||||||
_object_instance_extents[0].z = std::min(_object_instance_extents[0].z, instance->extents[0].z);
|
_object_instance_extents[0].z = std::min(_object_instance_extents[0].z, instance->getExtents()[0].z);
|
||||||
|
|
||||||
_object_instance_extents[1].x = std::max(_object_instance_extents[1].x, instance->extents[1].x);
|
_object_instance_extents[1].x = std::max(_object_instance_extents[1].x, instance->getExtents()[1].x);
|
||||||
_object_instance_extents[1].y = std::max(_object_instance_extents[1].y, instance->extents[1].y);
|
_object_instance_extents[1].y = std::max(_object_instance_extents[1].y, instance->getExtents()[1].y);
|
||||||
_object_instance_extents[1].z = std::max(_object_instance_extents[1].z, instance->extents[1].z);
|
_object_instance_extents[1].z = std::max(_object_instance_extents[1].z, instance->getExtents()[1].z);
|
||||||
|
|
||||||
tagCombinedExtents(true);
|
tagCombinedExtents(true);
|
||||||
}
|
}
|
||||||
@@ -1029,13 +1029,13 @@ void MapTile::add_model(SceneObject* instance)
|
|||||||
{
|
{
|
||||||
instance->ensureExtents();
|
instance->ensureExtents();
|
||||||
|
|
||||||
_object_instance_extents[0].x = std::min(_object_instance_extents[0].x, instance->extents[0].x);
|
_object_instance_extents[0].x = std::min(_object_instance_extents[0].x, instance->getExtents()[0].x);
|
||||||
_object_instance_extents[0].y = std::min(_object_instance_extents[0].y, instance->extents[0].y);
|
_object_instance_extents[0].y = std::min(_object_instance_extents[0].y, instance->getExtents()[0].y);
|
||||||
_object_instance_extents[0].z = std::min(_object_instance_extents[0].z, instance->extents[0].z);
|
_object_instance_extents[0].z = std::min(_object_instance_extents[0].z, instance->getExtents()[0].z);
|
||||||
|
|
||||||
_object_instance_extents[1].x = std::max(_object_instance_extents[1].x, instance->extents[1].x);
|
_object_instance_extents[1].x = std::max(_object_instance_extents[1].x, instance->getExtents()[1].x);
|
||||||
_object_instance_extents[1].y = std::max(_object_instance_extents[1].y, instance->extents[1].y);
|
_object_instance_extents[1].y = std::max(_object_instance_extents[1].y, instance->getExtents()[1].y);
|
||||||
_object_instance_extents[1].z = std::max(_object_instance_extents[1].z, instance->extents[1].z);
|
_object_instance_extents[1].z = std::max(_object_instance_extents[1].z, instance->getExtents()[1].z);
|
||||||
|
|
||||||
tagCombinedExtents(true);
|
tagCombinedExtents(true);
|
||||||
}
|
}
|
||||||
@@ -1714,8 +1714,8 @@ void MapTile::recalcObjectInstanceExtents()
|
|||||||
|
|
||||||
instance->ensureExtents();
|
instance->ensureExtents();
|
||||||
|
|
||||||
glm::vec3& min = instance->extents[0];
|
glm::vec3 min = instance->getExtents()[0];
|
||||||
glm::vec3& max = instance->extents[1];
|
glm::vec3 max = instance->getExtents()[1];
|
||||||
|
|
||||||
_object_instance_extents[0].x = std::min(_object_instance_extents[0].x, min.x);
|
_object_instance_extents[0].x = std::min(_object_instance_extents[0].x, min.x);
|
||||||
_object_instance_extents[0].y = std::min(_object_instance_extents[0].y, min.y);
|
_object_instance_extents[0].y = std::min(_object_instance_extents[0].y, min.y);
|
||||||
|
|||||||
@@ -6219,7 +6219,7 @@ void MapView::ShowContextMenu(QPoint pos)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// verify this
|
// verify this
|
||||||
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED | Noggit::ActionFlags::eOBJECTS_REMOVED); // Noggit::ActionFlags::eOBJECTS_TRANSFORMED
|
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED | Noggit::ActionFlags::eOBJECTS_REMOVED);
|
||||||
|
|
||||||
// get the model to replace by
|
// get the model to replace by
|
||||||
auto replace_select = objectEditor->getClipboard().front();
|
auto replace_select = objectEditor->getClipboard().front();
|
||||||
@@ -6278,10 +6278,6 @@ void MapView::ShowContextMenu(QPoint pos)
|
|||||||
new_obj->recalcExtents();
|
new_obj->recalcExtents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// can cause the usual crash of deleting models overlapping unloaded tiles.
|
|
||||||
// _world->delete_selected_models();
|
|
||||||
// NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED);
|
|
||||||
|
|
||||||
// this would also delete models that got skipped
|
// this would also delete models that got skipped
|
||||||
// _world->delete_selected_models();
|
// _world->delete_selected_models();
|
||||||
|
|
||||||
|
|||||||
@@ -219,14 +219,11 @@ void ModelInstance::ensureExtents()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3* ModelInstance::getExtents()
|
std::array<glm::vec3, 2> const& ModelInstance::getExtents()
|
||||||
{
|
{
|
||||||
if (_need_recalc_extents && model->finishedLoading())
|
ensureExtents();
|
||||||
{
|
|
||||||
recalcExtents();
|
|
||||||
}
|
|
||||||
|
|
||||||
return &extents[0];
|
return extents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
void ModelInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
||||||
@@ -282,6 +279,7 @@ wmo_doodad_instance::wmo_doodad_instance(BlizzardArchive::Listfile::FileKey cons
|
|||||||
|
|
||||||
f->read(ff, 16);
|
f->read(ff, 16);
|
||||||
doodad_orientation = glm::quat (-ff[0], -ff[2], ff[1], ff[3]);
|
doodad_orientation = glm::quat (-ff[0], -ff[2], ff[1], ff[3]);
|
||||||
|
dir = glm::eulerAngles(doodad_orientation);
|
||||||
|
|
||||||
f->read(&scale, 4);
|
f->read(&scale, 4);
|
||||||
|
|
||||||
@@ -301,12 +299,13 @@ wmo_doodad_instance::wmo_doodad_instance(BlizzardArchive::Listfile::FileKey cons
|
|||||||
|
|
||||||
void wmo_doodad_instance::update_transform_matrix_wmo(WMOInstance* wmo)
|
void wmo_doodad_instance::update_transform_matrix_wmo(WMOInstance* wmo)
|
||||||
{
|
{
|
||||||
if (!model->finishedLoading())
|
if (!model->finishedLoading() || !wmo->finishedLoading())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
world_pos = wmo->transformMatrix() * glm::vec4(pos,0);
|
// world_pos = wmo->transformMatrix() * glm::vec4(pos,0);
|
||||||
|
world_pos = wmo->transformMatrix() * glm::vec4(pos, 1.0f);
|
||||||
|
|
||||||
auto m2_mat = glm::mat4x4(1);
|
auto m2_mat = glm::mat4x4(1);
|
||||||
m2_mat = glm::translate(m2_mat, pos);
|
m2_mat = glm::translate(m2_mat, pos);
|
||||||
@@ -318,9 +317,11 @@ void wmo_doodad_instance::update_transform_matrix_wmo(WMOInstance* wmo)
|
|||||||
wmo->transformMatrix() * m2_mat
|
wmo->transformMatrix() * m2_mat
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_transform_mat = mat;
|
||||||
_transform_mat_inverted = glm::inverse(mat);
|
_transform_mat_inverted = glm::inverse(mat);
|
||||||
|
|
||||||
// to compute the size category (used in culling)
|
// to compute the size category (used in culling)
|
||||||
|
// updateTransformMatrix() is overriden to do nothing
|
||||||
recalcExtents();
|
recalcExtents();
|
||||||
|
|
||||||
_need_matrix_update = false;
|
_need_matrix_update = false;
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ public:
|
|||||||
void recalcExtents() override;
|
void recalcExtents() override;
|
||||||
void ensureExtents() override;
|
void ensureExtents() override;
|
||||||
bool finishedLoading() override { return model->finishedLoading(); };
|
bool finishedLoading() override { return model->finishedLoading(); };
|
||||||
glm::vec3* getExtents();
|
std::array<glm::vec3, 2> const& getExtents() override;
|
||||||
|
// glm::vec3* getExtents();
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
virtual bool isWMODoodad() const { return false; };
|
virtual bool isWMODoodad() const { return false; };
|
||||||
@@ -121,18 +122,26 @@ class wmo_doodad_instance : public ModelInstance
|
|||||||
public:
|
public:
|
||||||
glm::quat doodad_orientation;
|
glm::quat doodad_orientation;
|
||||||
glm::vec3 world_pos;
|
glm::vec3 world_pos;
|
||||||
|
// local wmo group position is stored in modelInstance::pos
|
||||||
|
// same for scale
|
||||||
|
|
||||||
explicit wmo_doodad_instance(BlizzardArchive::Listfile::FileKey const& file_key
|
explicit wmo_doodad_instance(BlizzardArchive::Listfile::FileKey const& file_key
|
||||||
, BlizzardArchive::ClientFile* f
|
, BlizzardArchive::ClientFile* f
|
||||||
, Noggit::NoggitRenderContext context );
|
, Noggit::NoggitRenderContext context );
|
||||||
|
|
||||||
|
// titi : issue with those constructors: ModelInstance data is lost (scale, pos...)
|
||||||
|
/**/
|
||||||
wmo_doodad_instance(wmo_doodad_instance const& other)
|
wmo_doodad_instance(wmo_doodad_instance const& other)
|
||||||
: ModelInstance(other.model->file_key(), other._context)
|
// : ModelInstance(other.model->file_key(), other._context)
|
||||||
|
: ModelInstance(other) // titi : Use the copy constructor of ModelInstance instead
|
||||||
, doodad_orientation(other.doodad_orientation)
|
, doodad_orientation(other.doodad_orientation)
|
||||||
, world_pos(other.world_pos)
|
, world_pos(other.world_pos)
|
||||||
, _need_matrix_update(other._need_matrix_update)
|
, _need_matrix_update(other._need_matrix_update)
|
||||||
{
|
{
|
||||||
|
// titi: added those.
|
||||||
|
// pos = other.pos;
|
||||||
|
// scale = other.scale;
|
||||||
|
// frame = other.frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
wmo_doodad_instance& operator= (wmo_doodad_instance const& other) = delete;
|
wmo_doodad_instance& operator= (wmo_doodad_instance const& other) = delete;
|
||||||
@@ -153,6 +162,7 @@ public:
|
|||||||
std::swap (_need_matrix_update, other._need_matrix_update);
|
std::swap (_need_matrix_update, other._need_matrix_update);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool need_matrix_update() const { return _need_matrix_update; }
|
bool need_matrix_update() const { return _need_matrix_update; }
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
virtual AsyncObject* instance_model() const = 0;
|
virtual AsyncObject* instance_model() const = 0;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
std::array<glm::vec3, 2> const& getExtents() { ensureExtents(); return extents; }
|
virtual std::array<glm::vec3, 2> const& getExtents() { ensureExtents(); return extents; }
|
||||||
|
|
||||||
glm::vec3 const getServerPos() { return glm::vec3(ZEROPOINT - pos.z, ZEROPOINT - pos.x, pos.y); }
|
glm::vec3 const getServerPos() { return glm::vec3(ZEROPOINT - pos.z, ZEROPOINT - pos.x, pos.y); }
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
glm::vec3 pos;
|
glm::vec3 pos;
|
||||||
std::array<glm::vec3, 2> extents;
|
|
||||||
glm::vec3 dir;
|
glm::vec3 dir;
|
||||||
float scale = 1.f;
|
float scale = 1.f;
|
||||||
unsigned int uid;
|
unsigned int uid;
|
||||||
@@ -88,6 +88,7 @@ protected:
|
|||||||
|
|
||||||
glm::mat4x4 _transform_mat = glm::mat4x4();
|
glm::mat4x4 _transform_mat = glm::mat4x4();
|
||||||
glm::mat4x4 _transform_mat_inverted = glm::mat4x4();
|
glm::mat4x4 _transform_mat_inverted = glm::mat4x4();
|
||||||
|
std::array<glm::vec3, 2> extents;
|
||||||
|
|
||||||
Noggit::NoggitRenderContext _context;
|
Noggit::NoggitRenderContext _context;
|
||||||
|
|
||||||
|
|||||||
@@ -382,17 +382,17 @@ void selection_group::recalcExtents()
|
|||||||
|
|
||||||
// min = glm::min(min, point);
|
// min = glm::min(min, point);
|
||||||
if (instance->getExtents()[0].x < _group_extents[0].x)
|
if (instance->getExtents()[0].x < _group_extents[0].x)
|
||||||
_group_extents[0].x = instance->extents[0].x;
|
_group_extents[0].x = instance->getExtents()[0].x;
|
||||||
if (instance->getExtents()[0].y < _group_extents[0].y)
|
if (instance->getExtents()[0].y < _group_extents[0].y)
|
||||||
_group_extents[0].y = instance->extents[0].y;
|
_group_extents[0].y = instance->getExtents()[0].y;
|
||||||
if (instance->getExtents()[0].z < _group_extents[0].z)
|
if (instance->getExtents()[0].z < _group_extents[0].z)
|
||||||
_group_extents[0].z = instance->extents[0].z;
|
_group_extents[0].z = instance->getExtents()[0].z;
|
||||||
|
|
||||||
if (instance->getExtents()[1].x > _group_extents[1].x)
|
if (instance->getExtents()[1].x > _group_extents[1].x)
|
||||||
_group_extents[1].x = instance->extents[1].x;
|
_group_extents[1].x = instance->getExtents()[1].x;
|
||||||
if (instance->getExtents()[1].y > _group_extents[1].y)
|
if (instance->getExtents()[1].y > _group_extents[1].y)
|
||||||
_group_extents[1].y = instance->extents[1].y;
|
_group_extents[1].y = instance->getExtents()[1].y;
|
||||||
if (instance->getExtents()[1].z > _group_extents[1].z)
|
if (instance->getExtents()[1].z > _group_extents[1].z)
|
||||||
_group_extents[1].z = instance->extents[1].z;
|
_group_extents[1].z = instance->getExtents()[1].z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ void WMOGroup::load()
|
|||||||
}
|
}
|
||||||
|
|
||||||
center = (VertexBoxMax + VertexBoxMin) * 0.5f;
|
center = (VertexBoxMax + VertexBoxMin) * 0.5f;
|
||||||
rad = (VertexBoxMax - center).length () + 300.0f;;
|
rad = glm::distance(center, VertexBoxMax);
|
||||||
|
|
||||||
f.seekRelative (size);
|
f.seekRelative (size);
|
||||||
|
|
||||||
@@ -1080,18 +1080,39 @@ bool WMOGroup::is_visible( glm::mat4x4 const& transform
|
|||||||
, display_mode display
|
, display_mode display
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
glm::vec3 pos = transform * glm::vec4(center, 0);
|
// glm::vec3 pos = transform * glm::vec4(center, 0);
|
||||||
|
//
|
||||||
|
// glm::vec3 pos = transform[3] * glm::vec4(center, 1.0f);
|
||||||
|
// glm::vec3 test_pos = transform[3] + glm::vec4(center, 0);
|
||||||
|
// glm::vec3 test_pos2 = transform[3];
|
||||||
|
|
||||||
|
|
||||||
|
// TODO center is just the center of the group vertex box, and rad is distance from box max to center.
|
||||||
|
// to do operation on group we need to get its true position
|
||||||
|
//
|
||||||
|
// adjusted group transform mat =
|
||||||
|
glm::vec3 pos = transform * glm::vec4(center, 1.0f);
|
||||||
|
|
||||||
|
float dist = display == display_mode::in_3D
|
||||||
|
? glm::distance(pos, camera) - rad
|
||||||
|
: std::abs(pos.y - camera.y) - rad;
|
||||||
|
|
||||||
|
// Camera is within the bounding sphere, always draw
|
||||||
|
if (dist < 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
float cull = cull_distance;
|
||||||
|
|
||||||
|
if (dist > cull_distance)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
if (!frustum.intersects(pos + BoundingBoxMin, pos + BoundingBoxMax))
|
if (!frustum.intersects(pos + BoundingBoxMin, pos + BoundingBoxMax))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float dist = display == display_mode::in_3D
|
return true;
|
||||||
? glm::distance(pos, camera) - rad
|
|
||||||
: std::abs(pos.y - camera.y) - rad;
|
|
||||||
|
|
||||||
return (dist < cull_distance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ WMOInstance::WMOInstance(BlizzardArchive::Listfile::FileKey const& file_key, ENT
|
|||||||
extents[0] = glm::vec3(d->extents[0][0], d->extents[0][1], d->extents[0][2]);
|
extents[0] = glm::vec3(d->extents[0][0], d->extents[0][1], d->extents[0][2]);
|
||||||
extents[1] = glm::vec3(d->extents[1][0], d->extents[1][1], d->extents[1][2]);
|
extents[1] = glm::vec3(d->extents[1][0], d->extents[1][1], d->extents[1][2]);
|
||||||
|
|
||||||
|
_need_recalc_extents = true;
|
||||||
updateTransformMatrix();
|
updateTransformMatrix();
|
||||||
change_doodadset(_doodadset);
|
change_doodadset(_doodadset);
|
||||||
}
|
}
|
||||||
@@ -46,6 +47,7 @@ WMOInstance::WMOInstance(BlizzardArchive::Listfile::FileKey const& file_key, Nog
|
|||||||
uid = 0;
|
uid = 0;
|
||||||
_context = context;
|
_context = context;
|
||||||
|
|
||||||
|
_need_recalc_extents = true;
|
||||||
updateTransformMatrix();
|
updateTransformMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +74,8 @@ void WMOInstance::draw ( OpenGL::Scoped::use_program& wmo_shader
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensureExtents();
|
||||||
|
|
||||||
const uint id = this->uid;
|
const uint id = this->uid;
|
||||||
bool const is_selected = selection.size() > 0 &&
|
bool const is_selected = selection.size() > 0 &&
|
||||||
std::find_if(selection.begin(), selection.end(),
|
std::find_if(selection.begin(), selection.end(),
|
||||||
@@ -142,6 +146,8 @@ void WMOInstance::draw ( OpenGL::Scoped::use_program& wmo_shader
|
|||||||
|
|
||||||
void WMOInstance::intersect (math::ray const& ray, selection_result* results, bool do_exterior)
|
void WMOInstance::intersect (math::ray const& ray, selection_result* results, bool do_exterior)
|
||||||
{
|
{
|
||||||
|
ensureExtents();
|
||||||
|
|
||||||
if (!ray.intersect_bounds (extents[0], extents[1]))
|
if (!ray.intersect_bounds (extents[0], extents[1]))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -155,10 +161,19 @@ void WMOInstance::intersect (math::ray const& ray, selection_result* results, bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::array<glm::vec3, 2> const& WMOInstance::getExtents()
|
||||||
|
{
|
||||||
|
ensureExtents();
|
||||||
|
|
||||||
|
return extents;
|
||||||
|
}
|
||||||
|
|
||||||
void WMOInstance::ensureExtents()
|
void WMOInstance::ensureExtents()
|
||||||
{
|
{
|
||||||
recalcExtents();
|
if (_need_recalc_extents && wmo->finishedLoading())
|
||||||
// TODO: optimize
|
{
|
||||||
|
recalcExtents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WMOInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
void WMOInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
||||||
@@ -206,11 +221,18 @@ void WMOInstance::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
|||||||
|
|
||||||
void WMOInstance::recalcExtents()
|
void WMOInstance::recalcExtents()
|
||||||
{
|
{
|
||||||
// todo: keep track of whether the extents need to be recalculated or not
|
|
||||||
// keep the old extents since they are saved in the adt
|
// keep the old extents since they are saved in the adt
|
||||||
if (wmo->loading_failed() || !wmo->finishedLoading())
|
if (!wmo->finishedLoading())
|
||||||
{
|
{
|
||||||
return;
|
_need_recalc_extents = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wmo->loading_failed())
|
||||||
|
{
|
||||||
|
extents[0] = extents[1] = pos;
|
||||||
|
_need_recalc_extents = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTransformMatrix();
|
updateTransformMatrix();
|
||||||
@@ -246,7 +268,7 @@ void WMOInstance::recalcExtents()
|
|||||||
|
|
||||||
points.insert(points.end(), adjustedGroupPoints.begin(), adjustedGroupPoints.end());
|
points.insert(points.end(), adjustedGroupPoints.begin(), adjustedGroupPoints.end());
|
||||||
|
|
||||||
if (group.has_skybox() || _update_group_extents)
|
if (group.has_skybox() /* || _update_group_extents*/)
|
||||||
{
|
{
|
||||||
math::aabb const group_aabb(adjustedGroupPoints);
|
math::aabb const group_aabb(adjustedGroupPoints);
|
||||||
|
|
||||||
@@ -259,6 +281,8 @@ void WMOInstance::recalcExtents()
|
|||||||
|
|
||||||
extents[0] = wmo_aabb.min;
|
extents[0] = wmo_aabb.min;
|
||||||
extents[1] = wmo_aabb.max;
|
extents[1] = wmo_aabb.max;
|
||||||
|
|
||||||
|
_need_recalc_extents = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WMOInstance::change_nameset(uint16_t name_set)
|
void WMOInstance::change_nameset(uint16_t name_set)
|
||||||
@@ -284,6 +308,7 @@ void WMOInstance::change_doodadset(uint16_t doodad_set)
|
|||||||
_doodads_per_group = wmo->doodads_per_group(_doodadset);
|
_doodads_per_group = wmo->doodads_per_group(_doodadset);
|
||||||
_need_doodadset_update = false;
|
_need_doodadset_update = false;
|
||||||
|
|
||||||
|
ensureExtents();
|
||||||
update_doodads();
|
update_doodads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,8 +318,8 @@ void WMOInstance::update_doodads()
|
|||||||
{
|
{
|
||||||
for (auto& doodad : group_doodads.second)
|
for (auto& doodad : group_doodads.second)
|
||||||
{
|
{
|
||||||
if (!doodad.need_matrix_update())
|
// if (!doodad.need_matrix_update())
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
doodad.update_transform_matrix_wmo(this);
|
doodad.update_transform_matrix_wmo(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class WMOInstance : public SceneObject
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
scoped_wmo_reference wmo;
|
scoped_wmo_reference wmo;
|
||||||
std::map<int, std::pair<glm::vec3, glm::vec3>> group_extents;
|
|
||||||
uint16_t mFlags;
|
uint16_t mFlags;
|
||||||
uint16_t mUnknown;
|
uint16_t mUnknown;
|
||||||
uint16_t mNameset;
|
uint16_t mNameset;
|
||||||
@@ -29,10 +29,11 @@ private:
|
|||||||
void update_doodads();
|
void update_doodads();
|
||||||
|
|
||||||
uint16_t _doodadset;
|
uint16_t _doodadset;
|
||||||
|
std::map<int, std::pair<glm::vec3, glm::vec3>> group_extents;
|
||||||
std::map<uint32_t, std::vector<wmo_doodad_instance>> _doodads_per_group;
|
std::map<uint32_t, std::vector<wmo_doodad_instance>> _doodads_per_group;
|
||||||
bool _need_doodadset_update = true;
|
bool _need_doodadset_update = true;
|
||||||
bool _update_group_extents = false;
|
bool _update_group_extents = false;
|
||||||
|
bool _need_recalc_extents = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WMOInstance(BlizzardArchive::Listfile::FileKey const& file_key, ENTRY_MODF const* d, Noggit::NoggitRenderContext context);
|
WMOInstance(BlizzardArchive::Listfile::FileKey const& file_key, ENTRY_MODF const* d, Noggit::NoggitRenderContext context);
|
||||||
@@ -52,6 +53,7 @@ public:
|
|||||||
, _doodadset (other._doodadset)
|
, _doodadset (other._doodadset)
|
||||||
, _doodads_per_group(other._doodads_per_group)
|
, _doodads_per_group(other._doodads_per_group)
|
||||||
, _need_doodadset_update(other._need_doodadset_update)
|
, _need_doodadset_update(other._need_doodadset_update)
|
||||||
|
, _need_recalc_extents(other._need_recalc_extents)
|
||||||
{
|
{
|
||||||
std::swap (extents, other.extents);
|
std::swap (extents, other.extents);
|
||||||
pos = other.pos;
|
pos = other.pos;
|
||||||
@@ -80,6 +82,7 @@ public:
|
|||||||
std::swap(_transform_mat, other._transform_mat);
|
std::swap(_transform_mat, other._transform_mat);
|
||||||
std::swap(_transform_mat_inverted, other._transform_mat_inverted);
|
std::swap(_transform_mat_inverted, other._transform_mat_inverted);
|
||||||
std::swap(_context, other._context);
|
std::swap(_context, other._context);
|
||||||
|
std::swap(_need_recalc_extents, other._need_recalc_extents);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +105,7 @@ public:
|
|||||||
|
|
||||||
void intersect (math::ray const&, selection_result*, bool do_exterior = true);
|
void intersect (math::ray const&, selection_result*, bool do_exterior = true);
|
||||||
|
|
||||||
|
std::array<glm::vec3, 2> const& getExtents() override;
|
||||||
void recalcExtents() override;
|
void recalcExtents() override;
|
||||||
void change_nameset(uint16_t name_set);
|
void change_nameset(uint16_t name_set);
|
||||||
void ensureExtents() override;
|
void ensureExtents() override;
|
||||||
|
|||||||
@@ -1026,10 +1026,10 @@ bool World::isInIndoorWmoGroup(std::array<glm::vec3, 2> obj_bounds, glm::mat4x4
|
|||||||
if (group.is_indoor())
|
if (group.is_indoor())
|
||||||
{
|
{
|
||||||
// must call getGroupExtent() to initialize wmo_instance.group_extents
|
// must call getGroupExtent() to initialize wmo_instance.group_extents
|
||||||
// TODO : clear group extents to free memory ?
|
// clear group extents to free memory ?
|
||||||
auto& group_extents = wmo_instance.getGroupExtents().at(i);
|
auto& group_extents = wmo_instance.getGroupExtents().at(i);
|
||||||
|
|
||||||
// TODO : do a precise calculation instead of using axis aligned bounding boxes.
|
|
||||||
bool aabb_test = obj_bounds[1].x >= group_extents.first.x
|
bool aabb_test = obj_bounds[1].x >= group_extents.first.x
|
||||||
&& obj_bounds[1].y >= group_extents.first.y
|
&& obj_bounds[1].y >= group_extents.first.y
|
||||||
&& obj_bounds[1].z >= group_extents.first.z
|
&& obj_bounds[1].z >= group_extents.first.z
|
||||||
@@ -1037,6 +1037,7 @@ bool World::isInIndoorWmoGroup(std::array<glm::vec3, 2> obj_bounds, glm::mat4x4
|
|||||||
&& group_extents.second.y >= obj_bounds[0].y
|
&& group_extents.second.y >= obj_bounds[0].y
|
||||||
&& group_extents.second.z >= obj_bounds[0].z;
|
&& group_extents.second.z >= obj_bounds[0].z;
|
||||||
|
|
||||||
|
// TODO : do a precise calculation instead of using axis aligned bounding boxes.
|
||||||
if (aabb_test) // oriented box check
|
if (aabb_test) // oriented box check
|
||||||
{
|
{
|
||||||
/* TODO
|
/* TODO
|
||||||
@@ -3046,7 +3047,7 @@ float World::getMaxTileHeight(const TileIndex& tile)
|
|||||||
{
|
{
|
||||||
auto obj = std::get<selected_object_type>(instance.value());
|
auto obj = std::get<selected_object_type>(instance.value());
|
||||||
obj->ensureExtents();
|
obj->ensureExtents();
|
||||||
max_height = std::max(max_height, std::max(obj->extents[0].y, obj->extents[1].y));
|
max_height = std::max(max_height, std::max(obj->getExtents()[0].y, obj->getExtents()[1].y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -919,10 +919,10 @@ uid_fix_status MapIndex::fixUIDs (World* world, bool cancel_on_model_loading_err
|
|||||||
loading_error |= instance.model->loading_failed();
|
loading_error |= instance.model->loading_failed();
|
||||||
|
|
||||||
// to avoid going outside of bound
|
// to avoid going outside of bound
|
||||||
std::size_t sx = std::max((std::size_t)(instance.extents[0].x / TILESIZE), (std::size_t)0);
|
std::size_t sx = std::max((std::size_t)(instance.getExtents()[0].x / TILESIZE), (std::size_t)0);
|
||||||
std::size_t sz = std::max((std::size_t)(instance.extents[0].z / TILESIZE), (std::size_t)0);
|
std::size_t sz = std::max((std::size_t)(instance.getExtents()[0].z / TILESIZE), (std::size_t)0);
|
||||||
std::size_t ex = std::min((std::size_t)(instance.extents[1].x / TILESIZE), (std::size_t)63);
|
std::size_t ex = std::min((std::size_t)(instance.getExtents()[1].x / TILESIZE), (std::size_t)63);
|
||||||
std::size_t ez = std::min((std::size_t)(instance.extents[1].z / TILESIZE), (std::size_t)63);
|
std::size_t ez = std::min((std::size_t)(instance.getExtents()[1].z / TILESIZE), (std::size_t)63);
|
||||||
|
|
||||||
auto const real_uid (world->add_model_instance (std::move(instance), false, false));
|
auto const real_uid (world->add_model_instance (std::move(instance), false, false));
|
||||||
|
|
||||||
@@ -944,10 +944,10 @@ uid_fix_status MapIndex::fixUIDs (World* world, bool cancel_on_model_loading_err
|
|||||||
instance.recalcExtents();
|
instance.recalcExtents();
|
||||||
// no need to check if the loading is finished since the extents are stored inside the adt
|
// no need to check if the loading is finished since the extents are stored inside the adt
|
||||||
// to avoid going outside of bound
|
// to avoid going outside of bound
|
||||||
std::size_t sx = std::max((std::size_t)(instance.extents[0].x / TILESIZE), (std::size_t)0);
|
std::size_t sx = std::max((std::size_t)(instance.getExtents()[0].x / TILESIZE), (std::size_t)0);
|
||||||
std::size_t sz = std::max((std::size_t)(instance.extents[0].z / TILESIZE), (std::size_t)0);
|
std::size_t sz = std::max((std::size_t)(instance.getExtents()[0].z / TILESIZE), (std::size_t)0);
|
||||||
std::size_t ex = std::min((std::size_t)(instance.extents[1].x / TILESIZE), (std::size_t)63);
|
std::size_t ex = std::min((std::size_t)(instance.getExtents()[1].x / TILESIZE), (std::size_t)63);
|
||||||
std::size_t ez = std::min((std::size_t)(instance.extents[1].z / TILESIZE), (std::size_t)63);
|
std::size_t ez = std::min((std::size_t)(instance.getExtents()[1].z / TILESIZE), (std::size_t)63);
|
||||||
|
|
||||||
auto const real_uid (world->add_wmo_instance (std::move(instance), false, false));
|
auto const real_uid (world->add_wmo_instance (std::move(instance), false, false));
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
|||||||
{
|
{
|
||||||
if (wmo.wmo->finishedLoading() && wmo.wmo->skybox)
|
if (wmo.wmo->finishedLoading() && wmo.wmo->skybox)
|
||||||
{
|
{
|
||||||
if (wmo.group_extents.empty())
|
if (wmo.getGroupExtents().empty())
|
||||||
{
|
{
|
||||||
wmo.recalcExtents();
|
wmo.recalcExtents();
|
||||||
}
|
}
|
||||||
@@ -205,9 +205,9 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
|||||||
, _cull_distance
|
, _cull_distance
|
||||||
, _world->animtime
|
, _world->animtime
|
||||||
, draw_model_animations
|
, draw_model_animations
|
||||||
, wmo.extents[0]
|
, wmo.getExtents()[0]
|
||||||
, wmo.extents[1]
|
, wmo.getExtents()[1]
|
||||||
, wmo.group_extents
|
, wmo.getGroupExtents()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,9 +450,52 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
|||||||
|
|
||||||
auto wmo_instance = static_cast<WMOInstance*>(instance);
|
auto wmo_instance = static_cast<WMOInstance*>(instance);
|
||||||
|
|
||||||
if (tile->renderer()->objectsFrustumCullTest() > 1 || frustum.intersects(wmo_instance->extents[1], wmo_instance->extents[0]))
|
if (tile->renderer()->objectsFrustumCullTest() > 1 || frustum.intersects(wmo_instance->getExtents()[1], wmo_instance->getExtents()[0]))
|
||||||
{
|
{
|
||||||
wmos_to_draw.push_back(wmo_instance);
|
wmos_to_draw.push_back(wmo_instance);
|
||||||
|
|
||||||
|
if (draw_wmo_doodads)
|
||||||
|
{
|
||||||
|
// auto doodads = wmo_instance->get_visible_doodads(frustum, _cull_distance, camera_pos, draw_hidden_models, display);
|
||||||
|
//
|
||||||
|
// for (auto& doodad : doodads)
|
||||||
|
// {
|
||||||
|
// if (doodad->frame == frame)
|
||||||
|
// continue;
|
||||||
|
// doodad->frame = frame;
|
||||||
|
//
|
||||||
|
// auto& instances = models_to_draw[doodad->model.get()];
|
||||||
|
//
|
||||||
|
// instances.push_back(doodad->transformMatrix());
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// doodad->isInFrustum(frustum);
|
||||||
|
|
||||||
|
std::map<uint32_t, std::vector<wmo_doodad_instance>>* doodads = wmo_instance->get_doodads(draw_hidden_models);
|
||||||
|
|
||||||
|
if (!doodads)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto& pair : *doodads)
|
||||||
|
{
|
||||||
|
for (auto& doodad : pair.second)
|
||||||
|
{
|
||||||
|
if (doodad.frame == frame)
|
||||||
|
continue;
|
||||||
|
doodad.frame = frame;
|
||||||
|
|
||||||
|
auto& instances = models_to_draw[doodad.model.get()];
|
||||||
|
|
||||||
|
instances.push_back(doodad.transformMatrix());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -634,7 +677,7 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
|||||||
std::unordered_map<Model*, std::size_t> model_boxes_to_draw;
|
std::unordered_map<Model*, std::size_t> model_boxes_to_draw;
|
||||||
|
|
||||||
{
|
{
|
||||||
if (draw_models || (minimap_render && minimap_render_settings->use_filters))
|
if (draw_models || draw_doodads_wmo || (minimap_render && minimap_render_settings->use_filters))
|
||||||
{
|
{
|
||||||
OpenGL::Scoped::use_program m2_shader {*_m2_instanced_program.get()};
|
OpenGL::Scoped::use_program m2_shader {*_m2_instanced_program.get()};
|
||||||
|
|
||||||
|
|||||||
@@ -54,13 +54,13 @@ void ObjectInstanceInfoNode::compute()
|
|||||||
|
|
||||||
if (_out_ports[3].connected)
|
if (_out_ports[3].connected)
|
||||||
{
|
{
|
||||||
_out_ports[3].out_value = std::make_shared<Vector3DData>(obj->extents[0]);
|
_out_ports[3].out_value = std::make_shared<Vector3DData>(obj->getExtents()[0]);
|
||||||
_node->onDataUpdated(3);
|
_node->onDataUpdated(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_out_ports[4].connected)
|
if (_out_ports[4].connected)
|
||||||
{
|
{
|
||||||
_out_ports[4].out_value = std::make_shared<Vector3DData>(obj->extents[1]);
|
_out_ports[4].out_value = std::make_shared<Vector3DData>(obj->getExtents()[1]);
|
||||||
_node->onDataUpdated(4);
|
_node->onDataUpdated(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -394,8 +394,8 @@ std::vector<glm::vec3> PreviewRenderer::calcSceneExtents()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
min[i] = std::min(instance.extents[0][i], min[i]);
|
min[i] = std::min(instance.getExtents()[0][i], min[i]);
|
||||||
max[i] = std::max(instance.extents[1][i], max[i]);
|
max[i] = std::max(instance.getExtents()[1][i], max[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,8 +403,8 @@ std::vector<glm::vec3> PreviewRenderer::calcSceneExtents()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
min[i] = std::min(instance.extents[0][i], min[i]);
|
min[i] = std::min(instance.getExtents()[0][i], min[i]);
|
||||||
max[i] = std::max(instance.extents[1][i], max[i]);
|
max[i] = std::max(instance.getExtents()[1][i], max[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user