Working on game states

This commit is contained in:
Vladislav Khorev committed 2026-06-18 20:51:44 +03:00
1 parent 0ca00f965d
commit e0968b5522
10 files changed
+340 -251

No files matched your search

+52 -52
View File
@@ -212,12 +212,12 @@ namespace ZL
const bool isSelected = (idx == selectedInteractiveObjectIndex);
// --- bounds box ---
if (obj.boundsMin != zero || obj.boundsMax != zero) {
if (obj.state.boundsMin != zero || obj.state.boundsMax != zero) {
const Eigen::Vector3f& color = isSelected ? colorSelected : colorDefault;
const float x0 = obj.boundsMin.x(), x1 = obj.boundsMax.x();
const float y0 = obj.boundsMin.y(), y1 = obj.boundsMax.y();
const float z0 = obj.boundsMin.z(), z1 = obj.boundsMax.z();
const float x0 = obj.state.boundsMin.x(), x1 = obj.state.boundsMax.x();
const float y0 = obj.state.boundsMin.y(), y1 = obj.state.boundsMax.y();
const float z0 = obj.state.boundsMin.z(), z1 = obj.state.boundsMax.z();
Eigen::Vector3f corners[8] = {
{ x0, y0, z0 }, { x1, y0, z0 },
@@ -227,12 +227,12 @@ namespace ZL
};
// Apply the same TRS the draw function applies: scale → rotateY → translate
if (obj.scale != 1.f) {
for (auto& c : corners) c *= obj.scale;
if (obj.state.scale != 1.f) {
for (auto& c : corners) c *= obj.state.scale;
}
if (obj.rotationY != 0.f) {
const float cosR = std::cos(obj.rotationY);
const float sinR = std::sin(obj.rotationY);
if (obj.state.rotationY != 0.f) {
const float cosR = std::cos(obj.state.rotationY);
const float sinR = std::sin(obj.state.rotationY);
for (auto& c : corners) {
const float nx = c.x() * cosR - c.z() * sinR;
const float nz = c.x() * sinR + c.z() * cosR;
@@ -240,7 +240,7 @@ namespace ZL
c.z() = nz;
}
}
for (auto& c : corners) c += obj.position;
for (auto& c : corners) c += obj.state.position;
VertexRenderStruct mesh;
mesh.data = CreateBoundsBoxMesh(corners, color);
@@ -249,8 +249,8 @@ namespace ZL
}
// --- interaction position pole ---
if (obj.hasInteractionPosition) {
const Eigen::Vector3f& p = obj.interactionPosition;
if (obj.state.hasInteractionPosition) {
const Eigen::Vector3f& p = obj.state.interactionPosition;
static constexpr float hw = 0.05f; // half width/depth
static constexpr float hh = 1.5f; // half height (pole = 3.0 tall)
@@ -312,8 +312,8 @@ namespace ZL
if (ctrlHeld) {
// Set the interaction position for the selected object (world XZ, Y=0).
auto& target = loc.interactiveObjects[selectedInteractiveObjectIndex];
target.interactionPosition = Eigen::Vector3f(worldHit.x(), 0.f, worldHit.z());
target.hasInteractionPosition = true;
target.state.interactionPosition = Eigen::Vector3f(worldHit.x(), 0.f, worldHit.z());
target.state.hasInteractionPosition = true;
boundsClickCount = 0; // cancel any in-progress bounds placement
buildInteractiveObjectBoundsMeshes();
std::cout << "[IO_EDITOR] Interaction position set on object " << selectedInteractiveObjectIndex
@@ -326,17 +326,17 @@ namespace ZL
// Convert world-space hit to object local space (inverse of scale → rotateY → translate)
auto worldToLocal = [&](const Eigen::Vector3f& w) -> Eigen::Vector3f {
Eigen::Vector3f local = w - obj.position;
if (obj.rotationY != 0.f) {
const float c = std::cos(-obj.rotationY);
const float s = std::sin(-obj.rotationY);
Eigen::Vector3f local = w - obj.state.position;
if (obj.state.rotationY != 0.f) {
const float c = std::cos(-obj.state.rotationY);
const float s = std::sin(-obj.state.rotationY);
const float nx = local.x() * c - local.z() * s;
const float nz = local.x() * s + local.z() * c;
local.x() = nx;
local.z() = nz;
}
if (obj.scale > 1e-6f && obj.scale != 1.f)
local /= obj.scale;
if (obj.state.scale > 1e-6f && obj.state.scale != 1.f)
local /= obj.state.scale;
return local;
};
@@ -350,9 +350,9 @@ namespace ZL
const Eigen::Vector3f localB = worldToLocal(worldHit);
auto& target = loc.interactiveObjects[selectedInteractiveObjectIndex];
target.boundsMin = Eigen::Vector3f(
target.state.boundsMin = Eigen::Vector3f(
min(localA.x(), localB.x()), 0.f, min(localA.z(), localB.z()));
target.boundsMax = Eigen::Vector3f(
target.state.boundsMax = Eigen::Vector3f(
max(localA.x(), localB.x()), 1.f, max(localA.z(), localB.z()));
boundsClickCount = 0;
@@ -360,8 +360,8 @@ namespace ZL
std::cout << "[IO_EDITOR] Bounds set on object " << selectedInteractiveObjectIndex
<< " (" << target.loadedObject.name << ")"
<< " min=(" << target.boundsMin.x() << ", " << target.boundsMin.z() << ")"
<< " max=(" << target.boundsMax.x() << ", " << target.boundsMax.z() << ")\n";
<< " min=(" << target.state.boundsMin.x() << ", " << target.state.boundsMin.z() << ")"
<< " max=(" << target.state.boundsMax.x() << ", " << target.state.boundsMax.z() << ")\n";
}
}
@@ -382,34 +382,34 @@ namespace ZL
for (const auto& obj : loc.interactiveObjects) {
json item;
item["name"] = obj.loadedObject.name;
item["texturePath"] = obj.loadedObject.texturePath;
if (!obj.loadedObject.textureDarkandsPath.empty())
item["textureDarkandsPath"] = obj.loadedObject.textureDarkandsPath;
item["meshPath"] = obj.loadedObject.meshPath;
item["rotationX"] = obj.loadedObject.meshRotationX;
item["rotationY"] = obj.loadedObject.meshRotationY;
item["rotationZ"] = obj.loadedObject.meshRotationZ;
item["positionX"] = obj.jsonPositionX;
item["positionY"] = obj.jsonPositionY;
item["positionZ"] = obj.jsonPositionZ;
item["scale"] = obj.loadedObject.meshScale;
item["interactionRadius"] = obj.interactionRadius;
item["approachRadius"] = obj.approachRadius;
if (!obj.activateFunctionName.empty())
item["activateFunction"] = obj.activateFunctionName;
item["pivotX"] = obj.pivot.x();
item["pivotY"] = obj.pivot.y();
item["pivotZ"] = obj.pivot.z();
item["boundsMinX"] = obj.boundsMin.x();
item["boundsMinY"] = obj.boundsMin.y();
item["boundsMinZ"] = obj.boundsMin.z();
item["boundsMaxX"] = obj.boundsMax.x();
item["boundsMaxY"] = obj.boundsMax.y();
item["boundsMaxZ"] = obj.boundsMax.z();
if (obj.hasInteractionPosition) {
item["interactionPositionX"] = obj.interactionPosition.x();
item["interactionPositionY"] = obj.interactionPosition.y();
item["interactionPositionZ"] = obj.interactionPosition.z();
item["texturePath"] = obj.loadedObject.creationInfo.texturePath;
if (!obj.loadedObject.creationInfo.textureDarkandsPath.empty())
item["textureDarkandsPath"] = obj.loadedObject.creationInfo.textureDarkandsPath;
item["meshPath"] = obj.loadedObject.creationInfo.meshPath;
item["rotationX"] = obj.loadedObject.creationInfo.meshRotationX;
item["rotationY"] = obj.loadedObject.creationInfo.meshRotationY;
item["rotationZ"] = obj.loadedObject.creationInfo.meshRotationZ;
item["positionX"] = obj.state.jsonPositionX;
item["positionY"] = obj.state.jsonPositionY;
item["positionZ"] = obj.state.jsonPositionZ;
item["scale"] = obj.loadedObject.creationInfo.meshScale;
item["interactionRadius"] = obj.state.interactionRadius;
item["approachRadius"] = obj.state.approachRadius;
if (!obj.state.activateFunctionName.empty())
item["activateFunction"] = obj.state.activateFunctionName;
item["pivotX"] = obj.state.pivot.x();
item["pivotY"] = obj.state.pivot.y();
item["pivotZ"] = obj.state.pivot.z();
item["boundsMinX"] = obj.state.boundsMin.x();
item["boundsMinY"] = obj.state.boundsMin.y();
item["boundsMinZ"] = obj.state.boundsMin.z();
item["boundsMaxX"] = obj.state.boundsMax.x();
item["boundsMaxY"] = obj.state.boundsMax.y();
item["boundsMaxZ"] = obj.state.boundsMax.z();
if (obj.state.hasInteractionPosition) {
item["interactionPositionX"] = obj.state.interactionPosition.x();
item["interactionPositionY"] = obj.state.interactionPosition.y();
item["interactionPositionZ"] = obj.state.interactionPosition.z();
}
j["objects"].push_back(item);
}