Character hair physics implementation

This commit is contained in:
2026-06-16 01:22:20 +03:00
parent 765dffbed0
commit 0a5edacf8a
26 changed files with 1629 additions and 225 deletions
+23 -11
View File
@@ -232,22 +232,34 @@ struct GUIListener : public Ogre::RenderTargetListener {
float width = size.x;
float height = size.y;
Ogre::Camera *camera = ECS::get<Camera>().mCamera;
// 1. Convert to camera space
// 1. Convert to camera space (OGRE camera looks down -Z)
Ogre::Vector3 eyeSpacePoint =
camera->getViewMatrix() * worldPoint;
// 2. Project to clip space
Ogre::Vector3 clipSpacePoint =
camera->getProjectionMatrix() * eyeSpacePoint;
if (clipSpacePoint.z < 0.0f)
if (eyeSpacePoint.z >= 0.0f)
return Ogre::Vector2(-1, -1);
// 3. Convert from clip space (-1 to 1) to screen space (0 to 1)
// Note: Y is usually flipped in API screen coordinates compared to projection
float screenX = (clipSpacePoint.x / 2.0f) + 0.5f;
float screenY = 1.0f - ((clipSpacePoint.y / 2.0f) + 0.5f);
// 2. Project to homogeneous clip space using Vector4 to preserve W
Ogre::Vector4 clipSpacePoint =
camera->getProjectionMatrix() *
Ogre::Vector4(eyeSpacePoint.x, eyeSpacePoint.y,
eyeSpacePoint.z, 1.0f);
if (clipSpacePoint.w <= 0.0f)
return Ogre::Vector2(-1, -1);
// 4. Map to actual pixel dimensions
// 3. Perspective divide to get NDC [-1, 1]
float ndcX = clipSpacePoint.x / clipSpacePoint.w;
float ndcY = clipSpacePoint.y / clipSpacePoint.w;
// 4. Convert NDC to screen space [0, 1], flipping Y for ImGui
float screenX = (ndcX * 0.5f) + 0.5f;
float screenY = 1.0f - ((ndcY * 0.5f) + 0.5f);
// 5. Reject if outside viewport bounds
if (screenX < 0.0f || screenX > 1.0f ||
screenY < 0.0f || screenY > 1.0f)
return Ogre::Vector2(-1, -1);
// 6. Map to actual pixel dimensions
return Ogre::Vector2(screenX * width, screenY * height);
}
void preview(const Ogre::RenderTargetViewportEvent &evt)