new default setting to rotate to ground on paste

This commit is contained in:
T1ti
2024-04-26 01:48:25 +02:00
parent c9ed5891a6
commit b1511fb669
4 changed files with 84 additions and 56 deletions

View File

@@ -390,25 +390,11 @@ void World::rotate_selected_models_randomly(float minX, float maxX, float minY,
}
}
void World::rotate_selected_models_to_ground_normal(bool smoothNormals)
void World::rotate_model_to_ground_normal(SceneObject* obj, bool smoothNormals)
{
ZoneScoped;
if (!_selected_model_count)
return;
selection_updated = true;
for (auto& entry : _current_selection)
{
auto type = entry.index();
if (type == eEntry_MapChunk)
{
continue;
}
auto& obj = std::get<selected_object_type>(entry);
NOGGIT_CUR_ACTION->registerObjectTransformed(obj);
updateTilesEntry(entry, model_update::remove);
updateTilesEntry(obj, model_update::remove);
glm::vec3 rayPos = obj->pos;
math::degrees::vec3& dir = obj->dir;
@@ -433,26 +419,26 @@ void World::rotate_selected_models_to_ground_normal(bool smoothNormals)
if (results.empty())
{
// just to avoid models disappearing when this happens
updateTilesEntry(entry, model_update::add);
continue;
updateTilesEntry(obj, model_update::add);
return;
}
// We hit the terrain, now we take the normal of this position and use it to get the rotation we want.
// We hit the terrain, now we take the normal of this position and use it to get the rotation we want.
auto const& hitChunkInfo = std::get<selected_chunk_type>(results.front().second);
glm::quat q;
glm::vec3 varnormal;
// Surface Normal
auto &p0 = hitChunkInfo.chunk->mVertices[std::get<0>(hitChunkInfo.triangle)];
auto &p1 = hitChunkInfo.chunk->mVertices[std::get<1>(hitChunkInfo.triangle)];
auto &p2 = hitChunkInfo.chunk->mVertices[std::get<2>(hitChunkInfo.triangle)];
auto& p0 = hitChunkInfo.chunk->mVertices[std::get<0>(hitChunkInfo.triangle)];
auto& p1 = hitChunkInfo.chunk->mVertices[std::get<1>(hitChunkInfo.triangle)];
auto& p2 = hitChunkInfo.chunk->mVertices[std::get<2>(hitChunkInfo.triangle)];
glm::vec3 v1 = p1 - p0;
glm::vec3 v2 = p2 - p0;
auto tmpVec = glm::cross(v2 ,v1);
auto tmpVec = glm::cross(v2, v1);
varnormal.x = tmpVec.z;
varnormal.y = tmpVec.y;
varnormal.z = tmpVec.x;
@@ -487,7 +473,7 @@ void World::rotate_selected_models_to_ground_normal(bool smoothNormals)
glm::vec3 worldUp = glm::vec3(0, 1, 0);
glm::vec3 a =glm::cross(worldUp ,varnormal);
glm::vec3 a = glm::cross(worldUp, varnormal);
q.x = a.x;
q.y = a.y;
@@ -527,12 +513,31 @@ void World::rotate_selected_models_to_ground_normal(bool smoothNormals)
dir.y = math::degrees(math::radians(eulerAngles.x))._; //Pitch
dir.z = math::degrees(math::radians(eulerAngles.y))._; //Yaw
std::get<selected_object_type>(entry)->recalcExtents();
obj->recalcExtents();
// yaw (z-axis rotation)
double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
updateTilesEntry(entry, model_update::add);
updateTilesEntry(obj, model_update::add);
}
void World::rotate_selected_models_to_ground_normal(bool smoothNormals)
{
ZoneScoped;
if (!_selected_model_count)
return;
selection_updated = true;
for (auto& entry : _current_selection)
{
auto type = entry.index();
if (type == eEntry_MapChunk)
{
continue;
}
auto& obj = std::get<selected_object_type>(entry);
rotate_model_to_ground_normal(obj, smoothNormals);
}
update_selected_model_groups();
}

View File

@@ -175,6 +175,7 @@ public:
// Checks the normal of the terrain on model origin and rotates to that spot.
void rotate_selected_models_to_ground_normal(bool smoothNormals);
void rotate_model_to_ground_normal(SceneObject* obj, bool smoothNormals);
bool GetVertex(float x, float z, glm::vec3 *V) const;

View File

@@ -203,6 +203,8 @@ namespace Noggit
QRadioButton *selectionButton = new QRadioButton("Selection");
QRadioButton *cameraButton = new QRadioButton("Camera");
QCheckBox* paste_override_rotate_cb = new QCheckBox("Rotate to Terrain", this);
pasteModeGroup = new QButtonGroup(this);
pasteModeGroup->addButton(terrainButton, 0);
pasteModeGroup->addButton(selectionButton, 1);
@@ -212,6 +214,8 @@ namespace Noggit
paste_layout->addWidget(selectionButton, 0, 1);
paste_layout->addWidget(cameraButton, 1, 0);
paste_layout->addWidget(paste_override_rotate_cb, 2, 0);
pasteBox->addPage(pasteBox_content);
auto object_movement_box (new QGroupBox("Single Selection Movement", this));
@@ -469,6 +473,12 @@ namespace Noggit
_use_median_pivot_point = b;
});
paste_override_rotate_cb->setChecked(paste_params->rotate_on_terrain);
connect(paste_override_rotate_cb, &QCheckBox::stateChanged, [=](int s)
{
paste_params->rotate_on_terrain = s;
});
connect ( pasteModeGroup, qOverload<int> (&QButtonGroup::idClicked)
, [&] (int id)
{
@@ -658,6 +668,12 @@ namespace Noggit
new_obj->model->waitForChildrenLoaded();
new_obj->recalcExtents();
if (paste_params->rotate_on_terrain)
{
// new_obj->pos.y = world->get_ground_height(new_obj->pos).y;// in multi select, objects aren't on the ground
world->rotate_model_to_ground_normal(new_obj, true); // always smooth?
}
// check if pos is valid (not in an interior) wmo group
// bool is_indoor = world->isInIndoorWmoGroup(new_obj->extents, new_obj->transformMatrix());
bool is_indoor = false; // TODO Disabled the indoor check until non axis aligned boxes check is implemented
@@ -685,6 +701,11 @@ namespace Noggit
new_obj->wmo->wait_until_loaded();
new_obj->wmo->waitForChildrenLoaded();
new_obj->recalcExtents();
if (paste_params->rotate_on_terrain)
{
world->rotate_model_to_ground_normal(new_obj, true); // always smooth?
}
}
}
}

View File

@@ -44,6 +44,7 @@ namespace Noggit
float maxTilt = 5.f;
float minScale = 0.9f;
float maxScale = 1.1f;
bool rotate_on_terrain = true;
};
namespace Ui