added inventory & active object

This commit is contained in:
Vlad committed 2026-04-09 15:33:55 +06:00
1 parent e1b491be73
commit b3fda88784
16 files changed
+793 -98

No files matched your search

+113
View File
@@ -50,6 +50,17 @@ namespace ZL {
data.scale = item.value("scale", 1.0f);
// Interactive object properties
data.interactive = item.value("interactive", false);
if (data.interactive && item.contains("item") && item["item"].is_object()) {
const auto& itemData = item["item"];
data.itemId = itemData.value("id", "");
data.itemName = itemData.value("name", "Unknown Item");
data.itemDescription = itemData.value("description", "");
data.itemIcon = itemData.value("icon", "");
data.interactionRadius = itemData.value("radius", 2.0f);
}
if (!data.meshPath.empty()) {
objects.push_back(data);
}
@@ -73,6 +84,8 @@ namespace ZL {
std::vector<GameObjectData> objectsData = loadFromJson(jsonPath, zipPath);
for (const auto& objData : objectsData) {
if (objData.interactive) continue; // Skip interactive objects, they're handled separately
std::cout << "Loading game object: " << objData.name << std::endl;
LoadedGameObject gameObj;
@@ -131,4 +144,104 @@ namespace ZL {
return gameObjects;
}
std::vector<InteractiveObject> GameObjectLoader::loadAndCreateInteractiveObjects(
const std::string& jsonPath,
Renderer& renderer,
const std::string& zipPath)
{
std::vector<InteractiveObject> interactiveObjects;
std::vector<GameObjectData> objectsData = loadFromJson(jsonPath, zipPath);
for (const auto& objData : objectsData) {
if (!objData.interactive) continue;
std::cout << "Loading interactive object: " << objData.name << std::endl;
InteractiveObject intObj;
intObj.id = objData.name;
intObj.name = objData.name;
intObj.interactionRadius = objData.interactionRadius;
// Load texture
try {
intObj.texture = std::make_shared<Texture>(CreateTextureDataFromPng(objData.texturePath, zipPath.c_str()));
}
catch (const std::exception& e) {
std::cerr << "GameObjectLoader: Failed to load texture for interactive '" << objData.name << "': " << e.what() << std::endl;
continue;
}
// Load mesh
try {
intObj.mesh.data = LoadFromTextFile02(objData.meshPath, zipPath);
}
catch (const std::exception& e) {
std::cerr << "GameObjectLoader: Failed to load mesh for interactive '" << objData.name << "': " << e.what() << std::endl;
continue;
}
// Apply rotation
Eigen::Quaternionf rotationQuat = Eigen::Quaternionf::Identity();
if (objData.rotationX != 0.0f) {
rotationQuat = Eigen::Quaternionf(Eigen::AngleAxisf(objData.rotationX, Eigen::Vector3f::UnitX())) * rotationQuat;
}
if (objData.rotationY != 0.0f) {
rotationQuat = Eigen::Quaternionf(Eigen::AngleAxisf(objData.rotationY, Eigen::Vector3f::UnitY())) * rotationQuat;
}
if (objData.rotationZ != 0.0f) {
rotationQuat = Eigen::Quaternionf(Eigen::AngleAxisf(objData.rotationZ, Eigen::Vector3f::UnitZ())) * rotationQuat;
}
intObj.mesh.data.RotateByMatrix(rotationQuat.toRotationMatrix());
// Apply scale
if (objData.scale != 1.0f) {
intObj.mesh.data.Scale(objData.scale);
}
intObj.mesh.RefreshVBO();
// Calculate mesh bounds to properly offset position
if (!intObj.mesh.data.PositionData.empty()) {
Eigen::Vector3f meshMin = intObj.mesh.data.PositionData[0];
Eigen::Vector3f meshMax = intObj.mesh.data.PositionData[0];
for (const auto& vert : intObj.mesh.data.PositionData) {
meshMin = meshMin.cwiseMin(vert);
meshMax = meshMax.cwiseMax(vert);
}
Eigen::Vector3f meshCenter = (meshMin + meshMax) * 0.5f;
std::cout << "[LOADER] Mesh bounds:" << std::endl;
std::cout << " Min: (" << meshMin.x() << ", " << meshMin.y() << ", " << meshMin.z() << ")" << std::endl;
std::cout << " Max: (" << meshMax.x() << ", " << meshMax.y() << ", " << meshMax.z() << ")" << std::endl;
std::cout << " Center: (" << meshCenter.x() << ", " << meshCenter.y() << ", " << meshCenter.z() << ")" << std::endl;
// Translate mesh so it's centered at origin
intObj.mesh.data.Move(-meshCenter);
intObj.mesh.RefreshVBO();
// Adjust position to account for mesh offset
intObj.position = Eigen::Vector3f(objData.positionX, objData.positionY, objData.positionZ) + meshCenter;
std::cout << "[LOADER] Corrected position: (" << intObj.position.x() << ", "
<< intObj.position.y() << ", " << intObj.position.z() << ")" << std::endl;
} else {
// Fallback if no vertices
intObj.position = Eigen::Vector3f(objData.positionX, objData.positionY, objData.positionZ);
}
// Create item
intObj.dropItem = Item(objData.itemId, objData.itemName, objData.itemDescription, objData.itemIcon);
interactiveObjects.push_back(intObj);
std::cout << "Successfully loaded interactive: " << objData.name << " (item: " << objData.itemName << ")" << std::endl;
}
std::cout << "Total interactive objects loaded: " << interactiveObjects.size() << std::endl;
return interactiveObjects;
}
} // namespace ZL
+13
View File
@@ -5,6 +5,7 @@
#include <unordered_map>
#include "external/nlohmann/json.hpp"
#include "TextModel.h"
#include "InteractiveObject.h"
namespace ZL {
@@ -23,6 +24,12 @@ namespace ZL {
float positionY = 0.0f;
float positionZ = 0.0f;
float scale = 1.0f;
bool interactive = false;
std::string itemId;
std::string itemName;
std::string itemDescription;
std::string itemIcon;
float interactionRadius = 2.0f;
};
struct LoadedGameObject {
@@ -40,6 +47,12 @@ namespace ZL {
Renderer& renderer,
const std::string& zipPath = ""
);
static std::vector<InteractiveObject> loadAndCreateInteractiveObjects(
const std::string& jsonPath,
Renderer& renderer,
const std::string& zipPath = ""
);
};
} // namespace ZL
+37
View File
@@ -0,0 +1,37 @@
#include "InteractiveObject.h"
#include "render/Renderer.h"
#include "render/TextureManager.h"
#include <iostream>
#include <string>
namespace ZL {
extern const std::string textureUniformName;
}
namespace ZL {
void InteractiveObject::draw(Renderer& renderer) const {
if (!isActive || !texture) return;
std::cout << "[DRAW] InteractiveObject::draw() called" << std::endl;
std::cout << "[DRAW] Object: " << name << std::endl;
std::cout << "[DRAW] Position: (" << position.x() << ", " << position.y() << ", " << position.z() << ")" << std::endl;
// Check mesh bounds
if (!mesh.data.PositionData.empty()) {
std::cout << "[DRAW] First vertex: (" << mesh.data.PositionData[0].x() << ", "
<< mesh.data.PositionData[0].y() << ", " << mesh.data.PositionData[0].z() << ")" << std::endl;
}
// Apply position transformation
renderer.PushMatrix();
renderer.TranslateMatrix(position);
renderer.RenderUniform1i(textureUniformName, 0);
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
renderer.DrawVertexRenderStruct(mesh);
renderer.PopMatrix();
}
} // namespace ZL
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include <string>
#include <memory>
#include <Eigen/Core>
#include "Item.h"
#include "render/Renderer.h"
namespace ZL {
struct Texture;
struct VertexRenderStruct;
class Renderer;
struct InteractiveObject {
std::string id;
std::string name;
Eigen::Vector3f position;
float interactionRadius;
std::shared_ptr<Texture> texture;
VertexRenderStruct mesh;
Item dropItem;
bool isActive = true;
InteractiveObject() : interactionRadius(2.0f) {}
bool isInRange(const Eigen::Vector3f& playerPos) const {
return (playerPos - position).norm() <= interactionRadius;
}
void draw(Renderer& renderer) const;
};
} // namespace ZL
+26
View File
@@ -0,0 +1,26 @@
#include "Item.h"
#include <algorithm>
#include <iostream>
namespace ZL {
void Inventory::addItem(const Item& item) {
items.push_back(item);
std::cout << "Item added to inventory: " << item.name << std::endl;
}
void Inventory::removeItem(const std::string& itemId) {
auto it = std::find_if(items.begin(), items.end(),
[&itemId](const Item& item) { return item.id == itemId; });
if (it != items.end()) {
std::cout << "Item removed from inventory: " << it->name << std::endl;
items.erase(it);
}
}
bool Inventory::hasItem(const std::string& itemId) const {
return std::find_if(items.begin(), items.end(),
[&itemId](const Item& item) { return item.id == itemId; }) != items.end();
}
} // namespace ZL
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include <string>
#include <memory>
#include <vector>
namespace ZL {
struct Item {
std::string id;
std::string name;
std::string description;
std::string icon;
Item() = default;
Item(const std::string& _id, const std::string& _name, const std::string& _desc, const std::string& _icon)
: id(_id), name(_name), description(_desc), icon(_icon) {
}
};
class Inventory {
private:
std::vector<Item> items;
public:
void addItem(const Item& item);
void removeItem(const std::string& itemId);
const std::vector<Item>& getItems() const { return items; }
bool hasItem(const std::string& itemId) const;
void clear() { items.clear(); }
size_t getCount() const { return items.size(); }
};
} // namespace ZL