I'm attempting to parent a bullethole decal to a dynamic object. I've figured out how to set the correct position for the bullethole object so that it shows at the correct position of the dynamic object, but once that dynamic object is rotated, parenting new bulletholes are skewed because I'm not compensating for the rotation of the dynamic object (the child object, bullethole decal in this case, is translated relative to the parent, which is why I'm attempting to remove the initial rotation of the parent object to get the actual rotation for the child). I've probably done a terrible job of explaining this...so here is a video of what I'm working on (note that the bulletholes that are added to the barrel before it is moved stay where they should be, and it's only after the barrel is rotated that new bulletholes become skewed)
So I believe I know what needs to happen, I'm just not sure how to go about implementing it. I need to compensate for the rotation of the barrel at the time the bullethole is parented to it, setting the rotation of the bullethole to this value. Possibly an easy question to answer for someone with experience working with quaternions.
if (raycast.hasHit())
{
auto hitPoint = vel::helpers::functions::bulletToGlmVec3(raycast.m_hitPointWorld);
bulletObject->currentPositionFromScreen = hitPoint;
bulletObject->disposeOnNextTick = true;
auto normal = vel::helpers::functions::bulletToGlmVec3(raycast.m_hitNormalWorld);
float nrmDot = glm::dot(normal, glm::vec3(0.0f, 1.0f, 0.0f));
auto bulletHoleAdjustmentValue = this->currentBulletHoleIndex == 0 ? 0.00001f : 0.00001f + (0.00001f * this->currentBulletHoleIndex);
auto bulletHolePosition = hitPoint + (normal * glm::vec3(bulletHoleAdjustmentValue, bulletHoleAdjustmentValue, bulletHoleAdjustmentValue));
auto bulletHoleActor = this->bulletHoleQueue.at(this->currentBulletHoleIndex);
if (this->currentBulletHoleIndex < (this->bulletHoleQueueSize - 1))
this->currentBulletHoleIndex++;
else
this->currentBulletHoleIndex = 0;
bulletHoleActor->getTransform().setTranslation(bulletHolePosition);
if (nrmDot < 1.0f && nrmDot > -1.0f)
bulletHoleActor->getTransform().setRotation(glm::toQuat(glm::transpose(glm::lookAt(hitPoint, bulletHolePosition, glm::vec3(0.0f, 1.0f, 0.0f)))));
else
bulletHoleActor->getTransform().setRotation(90.0f, glm::vec3(1.0f, 0.0f, 0.0f));
bulletHoleActor->setVisible(true);
// if physics object has a user pointer, parent bullethole actor to the actor which that value represents
if (raycast.m_collisionObject->getUserPointer() != nullptr)
{
auto dynamicActor = (vel::scene::stage::Actor*)raycast.m_collisionObject->getUserPointer();
bulletHolePosition = bulletHolePosition - dynamicActor->getTransform().getTranslation();
bulletHoleActor->getTransform().setTranslation(bulletHolePosition);
// Was thinking below would work, but it does not for some reason?
//auto newRotation = bulletHoleActor->getTransform().getRotation() * glm::inverse(dynamicActor->getTransform().getRotation());
//bulletHoleActor->getTransform().setRotation(newRotation);
bulletHoleActor->setParentActor(dynamicActor);
}
}