From e1415e917f4025e3483e7b2a9c77832a181cc5d1 Mon Sep 17 00:00:00 2001 From: floralrainfall Date: Tue, 18 Jul 2023 01:19:57 -0400 Subject: [PATCH] Humanoid --- .../RNR/textures/studio/icons/Humanoid.png | Bin 0 -> 1174 bytes .../Engine/Header/App/Humanoid/Humanoid.hpp | 19 ++++-- .../Header/App/Script/ReflectionProperty.hpp | 1 + .../Header/App/V8/DataModel/FaceInstance.hpp | 4 +- .../Engine/Header/App/V8/Tree/Instance.hpp | 4 ++ .../Header/App/V8/Tree/ModelInstance.hpp | 1 + .../Engine/Source/App/Humanoid/Humanoid.cpp | 55 ++++++++++++++++-- .../Source/App/Script/ReflectionProperty.cpp | 5 +- .../Source/App/V8/DataModel/FaceInstance.cpp | 10 +++- .../Engine/Source/App/V8/Tree/Instance.cpp | 25 ++++++++ .../Source/App/V8/Tree/ModelInstance.cpp | 10 ++++ .../Engine/Source/App/V8/Tree/PVInstance.cpp | 1 + Projects/Engine/Source/App/V8/World/World.cpp | 10 ++-- 13 files changed, 129 insertions(+), 16 deletions(-) create mode 100644 Content/RNR/textures/studio/icons/Humanoid.png diff --git a/Content/RNR/textures/studio/icons/Humanoid.png b/Content/RNR/textures/studio/icons/Humanoid.png new file mode 100644 index 0000000000000000000000000000000000000000..62775f89b1ce8d53d7de5e80c50b04696e7271e8 GIT binary patch literal 1174 zcmV;H1Zn$;P)EX>4Tx04R}tkv&MmKpe$iQ>7yH1MMKf)s6A|?JWDYS_3;J6>}?mh0_0Yam~RI@7vsG4P@ z6LB${TNMMZ2%sNBh+U4&e3JS*_Gq>z@3D!MwJz%ypV$NMI35NI`^*8p^1^LWEY06ccIMk9+t>9e;{kGP%lN zIZc;D~bidg4$2bt!1)6o+{yw(t<_X|`2ClTWzuEwzpQP8@ zTKEVU*aj}H+nT%wT$gU400009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-~x5(Neovgtz@0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbP zfJsC_R5;6Zlg&$1Q5c7xbMBol9Whfv%b*0a5+s5mXeHGU6)jo~^dIyAL7O%aMgKrS zt-_t;B5Yx_=o3n!pbs+=9Suj#k8#v#oI7*pUhg@lg(NmO@ABp02k-Mc2eufKCT7xH zFlkRD00zCMz{QUN{xidH0b!W@5-~*nBHj7eYV2QG^}%x~qOR~y-VAbhKB zhw1K^mh}|vZsvVklpO!`rHok*sF%?|b#OSLTJ3i}SL@o3Bh z%miUpX7ji!C1x_M&FfO@yQDCefc8p>Yg$Xd5Yj&G9~Uq0Vw3?OlW#6LZVUu9(THvW zI{ym@l%2}0)*xju7Il`qg>0E}ZoP7&g2LXWu^>)mYiWd!RIs$;yJS zE?cDq(84m25~>i#_{NlLV@G@X@-KlX@Cg{+aF9r*+(a@pIPI51MoUcuIm?)MeWJSNZX2A o&d}=pi7jO&3vYlqVC^6L7f{nZ4%kF@iU0rr07*qoM6N<$f(^b literal 0 HcmV?d00001 diff --git a/Projects/Engine/Header/App/Humanoid/Humanoid.hpp b/Projects/Engine/Header/App/Humanoid/Humanoid.hpp index 81769a2..197acff 100644 --- a/Projects/Engine/Header/App/Humanoid/Humanoid.hpp +++ b/Projects/Engine/Header/App/Humanoid/Humanoid.hpp @@ -1,23 +1,34 @@ #pragma once #include +#include namespace RNR { - class Humanoid : Instance + class Humanoid : public Instance { public: Humanoid(); ~Humanoid(); + + virtual std::string getClassName() { return "Humanoid"; } bool canSit(); void buildJoints(); void checkForJointDeath(); void computeForce(float force, bool throttling); - void getTorso(); - void getHead(); - + PartInstance* getTorso(); + PartInstance* getHead(); + + void createHealthBar(); + + float getHealth() { return m_health; }; + void setHealth(float health) { m_health = health; } + float getMaxHealth() { return m_maxHealth; } + void setMaxHealth(float maxHealth) { m_maxHealth = maxHealth; } private: + virtual void deserializeProperty(char* prop_name, pugi::xml_node prop); + virtual void addProperties(std::vector& properties); float m_health; float m_maxHealth; float m_walkRotationalVelocity; diff --git a/Projects/Engine/Header/App/Script/ReflectionProperty.hpp b/Projects/Engine/Header/App/Script/ReflectionProperty.hpp index e4ed259..e3c6942 100644 --- a/Projects/Engine/Header/App/Script/ReflectionProperty.hpp +++ b/Projects/Engine/Header/App/Script/ReflectionProperty.hpp @@ -40,6 +40,7 @@ namespace RNR PROPERTY_VECTOR3, PROPERTY_CFRAME, PROPERTY_INSTANCE, + PROPERTY_FLOAT, }; class ReflectionProperty diff --git a/Projects/Engine/Header/App/V8/DataModel/FaceInstance.hpp b/Projects/Engine/Header/App/V8/DataModel/FaceInstance.hpp index 823e166..531f5e1 100644 --- a/Projects/Engine/Header/App/V8/DataModel/FaceInstance.hpp +++ b/Projects/Engine/Header/App/V8/DataModel/FaceInstance.hpp @@ -11,6 +11,8 @@ namespace RNR NormalId m_face; public: - + FaceInstance(); + + virtual void build() = 0; }; } \ No newline at end of file diff --git a/Projects/Engine/Header/App/V8/Tree/Instance.hpp b/Projects/Engine/Header/App/V8/Tree/Instance.hpp index 361d617..a0a7a60 100644 --- a/Projects/Engine/Header/App/V8/Tree/Instance.hpp +++ b/Projects/Engine/Header/App/V8/Tree/Instance.hpp @@ -40,7 +40,11 @@ namespace RNR bool contains(RNR::Instance* child); bool isAncestorOf(RNR::Instance* instance); + bool isA(std::string type); + Instance* findFirstChild(std::string name); + Instance* findFirstChildOfType(std::string type); + static World* getWorld() { return Instance::world; } static void setWorld(World* world) { Instance::world = world; } diff --git a/Projects/Engine/Header/App/V8/Tree/ModelInstance.hpp b/Projects/Engine/Header/App/V8/Tree/ModelInstance.hpp index 1bc14ad..74f3ab2 100644 --- a/Projects/Engine/Header/App/V8/Tree/ModelInstance.hpp +++ b/Projects/Engine/Header/App/V8/Tree/ModelInstance.hpp @@ -11,6 +11,7 @@ namespace RNR virtual void build(); Ogre::AxisAlignedBox getBoundingBox() { return m_boundingbox; } virtual std::string getClassName() { return "Model"; } + virtual void onChildAdded(Instance* instance); private: Ogre::AxisAlignedBox m_boundingbox; diff --git a/Projects/Engine/Source/App/Humanoid/Humanoid.cpp b/Projects/Engine/Source/App/Humanoid/Humanoid.cpp index 13862e5..cf7c50d 100644 --- a/Projects/Engine/Source/App/Humanoid/Humanoid.cpp +++ b/Projects/Engine/Source/App/Humanoid/Humanoid.cpp @@ -1,4 +1,5 @@ #include +#include namespace RNR { @@ -32,13 +33,59 @@ namespace RNR // } - void Humanoid::getTorso() + void Humanoid::createHealthBar() { - // + if(!getHead()) + { + printf("Humanoid::createHealthBar: no head\n"); + return; + } + if(getNode()) + world->getOgreSceneManager()->destroySceneNode(getNode()); + setNode(world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode()); + Ogre::BillboardSet* healthBarSet = world->getOgreSceneManager()->createBillboardSet("HumanoidHealth" + getParent()->getName()); + Ogre::Billboard* healthBarBillboard = healthBarSet->createBillboard(Ogre::Vector3(100, 0, 200)); + getNode()->attachObject(healthBarSet); + getNode()->setPosition(getHead()->getPosition()); + + printf("Humanoid::createHealthBar: WIP"); } - void Humanoid::getHead() + void Humanoid::deserializeProperty(char* prop_name, pugi::xml_node prop) { - // + if(prop_name == std::string("Health")) + { + setHealth(prop.text().as_float()); + } + else if(prop_name == std::string("MaxHealth")) + { + setMaxHealth(prop.text().as_float()); + } + } + + void Humanoid::addProperties(std::vector& properties) + { + ReflectionProperty _properties[] = { + { this, std::string("Health"), std::string(""), + ACCESS_NONE, OPERATION_READWRITE, PROPERTY_FLOAT, + REFLECTION_GETTER(Humanoid* instance = (Humanoid*)object; return &instance->m_health; ), + REFLECTION_SETTER(Humanoid* instance = (Humanoid*)object; instance->setHealth(*(float*)value); ) }, + { this, std::string("MaxHealth"), std::string(""), + ACCESS_NONE, OPERATION_READWRITE, PROPERTY_FLOAT, + REFLECTION_GETTER(Humanoid* instance = (Humanoid*)object; return &instance->m_maxHealth; ), + REFLECTION_SETTER(Humanoid* instance = (Humanoid*)object; instance->setMaxHealth(*(float*)value); ) }, + }; + + properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty))); + } + + PartInstance* Humanoid::getTorso() + { + return (PartInstance*)getParent()->findFirstChild("Torso"); + } + + PartInstance* Humanoid::getHead() + { + return (PartInstance*)getParent()->findFirstChild("Head"); } } \ No newline at end of file diff --git a/Projects/Engine/Source/App/Script/ReflectionProperty.cpp b/Projects/Engine/Source/App/Script/ReflectionProperty.cpp index ca3bbb7..77dfa92 100644 --- a/Projects/Engine/Source/App/Script/ReflectionProperty.cpp +++ b/Projects/Engine/Source/App/Script/ReflectionProperty.cpp @@ -47,12 +47,15 @@ namespace RNR vector.y, vector.z); } + case PROPERTY_FLOAT: + return Strings::string_format("%f", + *(float*)m_getter(m_object)); case PROPERTY_CFRAME: { CoordinateFrame cframe = *(CoordinateFrame*)m_getter(m_object); Ogre::Vector3 cframe_position = cframe.getPosition(); Ogre::Quaternion cframe_rotation = Ogre::Quaternion(cframe.getRotation()); - return Strings::string_format("(%f,%f,%f)), (%f,%f,%f,%f)", + return Strings::string_format("(%f,%f,%f), (%f,%f,%f,%f)", cframe_position.x, cframe_position.y, cframe_position.z, diff --git a/Projects/Engine/Source/App/V8/DataModel/FaceInstance.cpp b/Projects/Engine/Source/App/V8/DataModel/FaceInstance.cpp index c64a5c2..228dbcd 100644 --- a/Projects/Engine/Source/App/V8/DataModel/FaceInstance.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/FaceInstance.cpp @@ -1,7 +1,15 @@ #include +#include +#include #include +#include namespace RNR { - + FaceInstance::FaceInstance() : Ogre::ManualObject(Strings::random_hex(8)) + { + setNode(world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode()); + getNode()->attachObject(this); + build(); + } } \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/Tree/Instance.cpp b/Projects/Engine/Source/App/V8/Tree/Instance.cpp index 06adae0..848c353 100644 --- a/Projects/Engine/Source/App/V8/Tree/Instance.cpp +++ b/Projects/Engine/Source/App/V8/Tree/Instance.cpp @@ -159,4 +159,29 @@ namespace RNR { } + + bool Instance::isA(std::string type) + { + if (type == getClassName()); // TODO: check if type is any of parent types + } + + Instance* Instance::findFirstChild(std::string name) + { + for(auto& child : m_children) + { + if(child->getName() == name) + return child; + } + return NULL; + } + + Instance* Instance::findFirstChildOfType(std::string type) + { + for(auto& child : m_children) + { + if(child->isA(type)) + return child; + } + return NULL; + } } \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/Tree/ModelInstance.cpp b/Projects/Engine/Source/App/V8/Tree/ModelInstance.cpp index 4eb6253..833732a 100644 --- a/Projects/Engine/Source/App/V8/Tree/ModelInstance.cpp +++ b/Projects/Engine/Source/App/V8/Tree/ModelInstance.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace RNR { @@ -27,4 +28,13 @@ namespace RNR m_boundingbox.merge(child_pv->getPosition() - size); } } + + void ModelInstance::onChildAdded(Instance* instance) + { + if(instance->getClassName() == "Humanoid") + { + Humanoid* instance_humanoid = (Humanoid*)instance; + instance_humanoid->createHealthBar(); + } + } } \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp b/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp index 6029dd5..f9502f2 100644 --- a/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp +++ b/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp @@ -1,4 +1,5 @@ #include +#include #include namespace RNR diff --git a/Projects/Engine/Source/App/V8/World/World.cpp b/Projects/Engine/Source/App/V8/World/World.cpp index dad12b7..f23405c 100644 --- a/Projects/Engine/Source/App/V8/World/World.cpp +++ b/Projects/Engine/Source/App/V8/World/World.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include namespace RNR @@ -46,6 +47,10 @@ namespace RNR { instance = new ModelInstance(); } + else if(class_attr.as_string() == std::string("Humanoid")) + { + instance = new Humanoid(); + } else { instance = new Instance(); @@ -67,11 +72,6 @@ namespace RNR { xmlAddItem(item, instance); } - - if(class_attr.as_string() == std::string("Model")) - { - ((ModelInstance*)instance)->build(); - } } void World::load(char* path)