Wie kann man mehrere Maschen um ihr gemeinsames Weltraumzentrum drehen?
Posted: 15 May 2025, 02:50
Hier ein Überblick über alle Gizmos in meiner Software:
Jetzt möchte ich ordnungsgemäß einige Maschen um ihre gemeinsame Mitte < /strong>. />
In meiner Software bekomme ich derzeit Folgendes:
grundlegend rot. Mitte.
Hier wird derzeit eine Mesh -endgültige Transformation berechnet:
[*]
MeshLocalTransform.
Die meshlocalTransform von BuildMeshWorldWorldSpacetRansform einfach von einem Mesh -Raum in ein Mesh -lokaler Raum nach Worldpace konvertieren. Transformationen werden unter Verwendung eines PRS (Position, Rotation, Skalierung) berechnet: < /p>
[*] Rotation Gizmo Transform. Hier wird die aktuelle Transformation im Rotations -Gizmo unter Verwendung der Benutzereingabe berechnet. < /P>
}
Jetzt möchte ich ordnungsgemäß einige Maschen um ihre gemeinsame Mitte < /strong>. />
In meiner Software bekomme ich derzeit Folgendes:
grundlegend rot. Mitte.
Hier wird derzeit eine Mesh -endgültige Transformation berechnet:
Code: Select all
Graphics::Transform buildMeshWorldSpaceTransform(const Graphics::Transform& meshLocalTransform, const Graphics::Transform& deltaTransformToApply, Math::Vec3 CenterWs)
{
Math::Vec3 scale;
Math::Vec3 orientation;// Not used because i can get glitches
Math::Vec3 position;
const Math::Mat4 mat = deltaTransformToApply.getMatrix() * meshLocalTransform.getMatrix();
Math::GlmExt::decompose(mat, scale, orientation, position);
Graphics::Transform transform;
transform.setPosition(position);
transform.setRotation(Graphics::EulerRotationAdd(deltaTransformToApply.getRotation(), meshLocalTransform.getRotation()));
transform.setScale(scale);
return transform;
}
< /code>
Da [b] CenterWs < /strong> nicht in Rechnung genommen wird. Es ist definitiv sinnvoll, dass die Rotation auf der ganzen Welt der Welt erfolgt.Graphics::Transform buildMeshWorldSpaceTransform(const Graphics::Transform& meshLocalTransform, const Graphics::Transform& deltaTransformToApply, Math::Vec3 CenterWs)
{
Math::Vec3 scale;
Math::Vec3 orientation;// Not used because i can get glitches
Math::Vec3 position;
const Math::Mat4 translationMatrix = glm::translate(Math::Mat4(), CenterWs);
const Math::Mat4 translationMatrixInv = glm::translate(Math::Mat4(), -CenterWs);
const Math::Mat4 mat = translationMatrix * deltaTransformToApply.getMatrix() * meshLocalTransform.getMatrix() * translationMatrixInv;
// @See: https://github.com/g-truc/glm/blob/master/glm/gtx/matrix_decompose.inl
Math::GlmExt::decompose(mat, scale, orientation, position);
Graphics::Transform transform;
transform.setPosition(position);
transform.setRotation(Graphics::EulerRotationAdd(deltaTransformToApply.getRotation(), meshLocalTransform.getRotation()));
transform.setScale(scale);
return transform;
}
< /code>
Mit diesem späteren Code erhalte ich das folgende Ergebnis:
[youtube]nwtcswc_gu8[/youtube]
Es startet gut, dann gibt es einen "Sprung". Siehe 0:16 < /p>
Ich habe dann einen weiteren Test gemacht, der den "Sprung" offensichtlicher macht. Grundsätzlich passiert es jedes Mal, wenn ich einen neuen Drag [/b]
[youtube]hgq-pb8y6b0[/youtube]
[b] Was [/b] mache ich mit dem neuen [b] buildMeshWorldSpacetransform [/b]? />https://www.dropbox.com/scl/fi/r5vu98c6ndin2Pf61jozv/transformModifierpanel Dies:
[img]https://i.sstatic.net/iVKC4pKj.png[/img]
The deltaTransformToApply from BuildMeshWorldSpacetRansform call ist einfach der Unterschied zwischen dem aktuellen und dem anfänglichen Transformationswert. Es wird wie folgt berechnet: < /p>
inline Transform buildDelta(const Transform& other) const
{
Transform outTransform;
outTransform.setPosition(getPosition() - other.getPosition());
outTransform.setRotation(EulerRotationSubstract(getRotation(), other.getRotation()));
outTransform.setScale(getScale() / other.getScale());
return outTransform;
}
MeshLocalTransform.
Die meshlocalTransform von BuildMeshWorldWorldSpacetRansform einfach von einem Mesh -Raum in ein Mesh -lokaler Raum nach Worldpace konvertieren. Transformationen werden unter Verwendung eines PRS (Position, Rotation, Skalierung) berechnet: < /p>
Code: Select all
inline void Transform::computeFromPRS(const Math::Vec3& position)
{
m_matrix = Math::Mat4();
m_matrix = glm::scale(m_matrix, m_scale);
m_matrix = glm::rotate(m_matrix, m_rotation[0].getValue(), Math::Vec3(1.0f, 0.0f, 0.0f));
m_matrix = glm::rotate(m_matrix, m_rotation[1].getValue(), Math::Vec3(0.0f, 1.0f, 0.0f));
m_matrix = glm::rotate(m_matrix, m_rotation[2].getValue(), Math::Vec3(0.0f, 0.0f, 1.0f));
m_matrix[3] = Math::Vec4(position.x, position.y, position.z, 1.0f);
}
Code: Select all
void RotationGizmo::onDrag(const Math::Ray& pixelRay)
< /code>
{
m_currentplane = getCurrentplane (); < /p>
nbFloat32 t;
if (m_currentPlane.intersect(pixelRay, t))
{
const Math::Vec3 interactionPos = pixelRay.getPoint(t);
const Math::Vec3 gizmoPos = getPosition();
const Math::Vec3 arm1 = glm::normalize(m_dragStartIsectPosition - gizmoPos);
const Math::Vec3 arm2 = glm::normalize(interactionPos - gizmoPos);
const float d = glm::dot(arm1, arm2);
Math::Vec3 orientation = eulerRotationToVec3(m_dragStartTransform.getRotation());
if (d = 0.001f)
{
const Math::Vec3 N = glm::swizzle(m_currentPlane.m_normal);
const Math::Vec3 planeCross = glm::cross(N, arm1);
// @See : https://math.stackexchange.com/questions/2140504/how-to-calculate-signed-angle-between-two-vectors-in-3d
if (glm::dot(planeCross, arm2) < 0.0f)
{
angle = Math::Pi2.getValue() - angle;
}
orientation += Math::Vec3(angle * Math::RadiansPerDegrees) * m_axisMultipliers[m_rotationType];
}
}
clampAngle(orientation.x);
clampAngle(orientation.y);
clampAngle(orientation.z);
auto transform = m_transform.lock();
const EulerRotation eulerRotation = vec3ToEulerRotation(orientation);
transform->setRotation(eulerRotation, false);
transform->notifyTransitionUpdate();
updateScaleFactor();
}