it works!

This commit is contained in:
Asuro
2025-03-30 00:05:52 +01:00
parent 3ce1acc633
commit e5076b0c3b
3 changed files with 83 additions and 39 deletions

View File

@@ -127,7 +127,7 @@ Vec3 Transform::GlobalToLocalDirection(Vec3 global)
bx::vec4MulMtx(out, in, MI.Transpose().M); bx::vec4MulMtx(out, in, MI.Transpose().M);
return {out[0], out[1], out[2]}; return {out[0], out[1], out[2]};
} }
bx::Vec3 Transform::GlobalToLocalPoint(Vec3 global) Vec3 Transform::GlobalToLocalPoint(Vec3 global)
{ {
UpdateMatrix(); UpdateMatrix();
float in[4]{global.x, global.y, global.z, 1.0f}; float in[4]{global.x, global.y, global.z, 1.0f};
@@ -143,7 +143,7 @@ Vec3 Transform::LocalToGlobalDirection(Vec3 local)
bx::vec4MulMtx(out, in, M.Transpose().M); bx::vec4MulMtx(out, in, M.Transpose().M);
return {out[0], out[1], out[2]}; return {out[0], out[1], out[2]};
} }
bx::Vec3 Transform::LocalToGlobalPoint(Vec3 local) Vec3 Transform::LocalToGlobalPoint(Vec3 local)
{ {
UpdateMatrix(); UpdateMatrix();
float in[4]{local.x, local.y, local.z, 1.0f}; float in[4]{local.x, local.y, local.z, 1.0f};
@@ -177,3 +177,38 @@ Vec4 Mat4::Mul(const Vec4& vec)
bx::vec4MulMtx(&out.x, &vec.x, &M[0]); bx::vec4MulMtx(&out.x, &vec.x, &M[0]);
return out; return out;
} }
float DotProduct(Vec3 a, Vec3 b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
Vec3 CrossProduct(Vec3 a, Vec3 b)
{
float x = a.y * b.z - a.z * b.y;
float y = a.z * b.x - a.x * b.z;
float z = a.x * b.y - a.y * b.x;
return {x, y, z};
}
Vec3 CrossProductFromPlane(Vec3 a, Vec3 b, Vec3 c)
{
// TODO: normalize might not be necessary
Vec3 lineA = (b - a).Normalize();
Vec3 lineB = (c - a).Normalize();
return CrossProduct(lineA, lineB);
}
bool RayPlaneIntersect(Vec3 l1, Vec3 l2, Vec3 p1, Vec3 p2, Vec3 p3, Vec3& out)
{
// thanks to Paul Bourke and Bryan Hanson
// l1,l2 constitute the line. P1,P2,P3 constitute the plane
out = {};
Vec3 N = CrossProductFromPlane(p1, p2, p3); // N is the normal of the plane
float n = DotProduct(N, Vec3{p3.x - l1.x, p3.y - l1.y, p3.z - l1.z});
Vec3 LbMinusLa = Vec3{l2.x - l1.x, l2.y - l1.y, l2.z - l1.z};
float d = DotProduct(N, LbMinusLa);
if (d == 0) return false; // Line is parallel to or in the plane
float u = n / d;
if ((u >= 0.0) && (u <= 1.0))
{ // Plane is between the two points
} // can be used for checking but does not influence the outcome
out = Vec3{l1.x + u * LbMinusLa.x, l1.y + u * LbMinusLa.y, l1.z + u * LbMinusLa.z};
return true;
}

View File

@@ -243,9 +243,9 @@ struct Transform
void TranslateLocal(Vec3 offset); void TranslateLocal(Vec3 offset);
void Rotate(Vec3 rotation); void Rotate(Vec3 rotation);
void RotateLocal(Vec3 rotation); void RotateLocal(Vec3 rotation);
bx::Vec3 LocalToGlobalPoint(Vec3 local); Vec3 LocalToGlobalPoint(Vec3 local);
Vec3 LocalToGlobalDirection(Vec3 local); Vec3 LocalToGlobalDirection(Vec3 local);
bx::Vec3 GlobalToLocalPoint(Vec3 global); Vec3 GlobalToLocalPoint(Vec3 global);
Vec3 GlobalToLocalDirection(Vec3 global); Vec3 GlobalToLocalDirection(Vec3 global);
Vec3 Right() const; Vec3 Right() const;
Vec3 Up() const; Vec3 Up() const;
@@ -257,6 +257,10 @@ struct Transform
void UpdateMatrixForCam(); void UpdateMatrixForCam();
}; };
Vec3 CrossProduct(Vec3 a, Vec3 b);
Vec3 CrossProductFromPlane(Vec3 a, Vec3 b, Vec3 c);
bool RayPlaneIntersect(Vec3 l1, Vec3 l2, Vec3 p1, Vec3 p2, Vec3 p3, Vec3& out);
struct SharedData; struct SharedData;
namespace Game namespace Game

View File

@@ -344,17 +344,14 @@ namespace Game
mousePos *= 2.0f; mousePos *= 2.0f;
mousePos -= 1.0f; mousePos -= 1.0f;
Vec4 mousePosView = {mousePos.x, -mousePos.y, 0.0f, 1.0f}; Vec4 mousePosView = {mousePos.x, -mousePos.y, 0.0f, 1.0f};
Vec4 mousePosCam = GetInstance().Player.ProjectionInverse.Mul(mousePosView); Vec4 mousePosCam4 = GetInstance().Player.ProjectionInverse.Mul(mousePosView);
mousePosCam.x /= mousePosCam.w; Vec3 mousePosCam = Vec3{
mousePosCam.y /= mousePosCam.w; mousePosCam4.x /= mousePosCam4.w,
mousePosCam.z /= mousePosCam.w; mousePosCam4.y /= mousePosCam4.w,
mousePosCam.w = 1.0f; mousePosCam4.z /= mousePosCam4.w,
Vec4 mousePosWorld = camTransform.M.Mul(mousePosCam); };
auto& t = level.Tests.Get({0}); Vec3 mousePosWorld = camTransform.LocalToGlobalPoint(mousePosCam);
t.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/cube.gltf");
t.EData.Transform.Position = {mousePosWorld.x, mousePosWorld.y, mousePosWorld.z};
t.EData.Transform.Scale = {0.01f, 0.01f, 0.01f};
for (int8_t y = 0; y < Data.HeightTiles / Puzzle::Config::CardSize; ++y) for (int8_t y = 0; y < Data.HeightTiles / Puzzle::Config::CardSize; ++y)
{ {
@@ -392,33 +389,41 @@ namespace Game
// quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f}; // quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f};
quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, bx::kPi}); quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, bx::kPi});
if (clicked && IsValid && x == 1 && y == 1) if (clicked && IsValid)
{ {
quad.EData.Transform.UpdateMatrix(); Vec3 quadPosWorld = quad.EData.Transform.GetPosition();
// boardTransform.UpdateMatrix(); Vec3 quadXWorld = quad.EData.Transform.LocalToGlobalPoint({1, 0, 0});
Vec4 posInQuad = quad.EData.Transform.MI.Mul(mousePosWorld); Vec3 quadYWorld = quad.EData.Transform.LocalToGlobalPoint({0, 0, 1});
// Vec4 posInQuad = boardTransform.MI.Mul(mousePosWorld); Vec3 intersectPos;
// if (posInQuad.x >= -1.0f && posInQuad.x <= 1.0f && posInQuad.z >= -1.0f && posInQuad.z <= 1.0f) if (RayPlaneIntersect(camTransform.GetPosition(),
mousePosWorld,
quadPosWorld,
quadXWorld,
quadYWorld,
intersectPos))
{ {
LOG("---"); Vec3 quadSpaceIntersect = quad.EData.Transform.GlobalToLocalPoint(intersectPos);
LOG("%.03f %.03f: Click", mousePos.x, mousePos.y); if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f &&
LOG("%.03f %.03f %.03f %.03f: Cam", mousePosCam.x, mousePosCam.y, mousePosCam.z, mousePosCam.w); quadSpaceIntersect.z >= -1.0f && quadSpaceIntersect.z <= 1.0f)
LOG("%.03f %.03f %.03f %.03f: World", {
mousePosWorld.x, // LOG("---");
mousePosWorld.y, // LOG("%.03f %.03f: Click", mousePos.x, mousePos.y);
mousePosWorld.z, // LOG("%.03f %.03f %.03f: MouseCam", mousePosCam.x, mousePosCam.y, mousePosCam.z);
mousePosWorld.w); // LOG("%.03f %.03f %.03f: MouseWorld", mousePosWorld.x, mousePosWorld.y, mousePosWorld.z);
LOG("%.03f %.03f %.03f %.03f: Card (%u %u)", // LOG("%.03f %.03f %.03f: Player",
posInQuad.x, // camTransform.Position.x,
posInQuad.y, // camTransform.Position.y,
posInQuad.z, // camTransform.Position.z);
posInQuad.w, // LOG("%.03f %.03f %.03f: QuadWorld", quadPosWorld.x, quadPosWorld.y, quadPosWorld.z);
x, // LOG("%.03f %.03f %.03f: QuadX", quadXWorld.x, quadXWorld.y, quadXWorld.z);
y); // LOG("%.03f %.03f %.03f: QuadY", quadYWorld.x, quadYWorld.y, quadYWorld.z);
LOG("%.03f %.03f %.03f: Player", // LOG("%.03f %.03f %.03f: Intersect", intersectPos.x, intersectPos.y, intersectPos.z);
camTransform.Position.x, // LOG("%.03f %.03f %.03f: IntersectQ",
camTransform.Position.y, // quadSpaceIntersect.x,
camTransform.Position.z); // quadSpaceIntersect.y,
// quadSpaceIntersect.z);
LOG("Clicked %u %u", x, y);
}
} }
} }
} }