Docs: Add audio module architecture design document
- Add XCEngine音频模块架构设计.md - Design audio system following Unity-style architecture - Include AudioSourceComponent, AudioListenerComponent, AudioClip, AudioMixer - Document DSP effect system (FFT, Reverb, EQ, Compressor) - Document 3D spatial audio with HRTF support - Define IAudioBackend abstraction layer with WASAPI/OpenAL backends - Outline 5-phase implementation priorities
This commit is contained in:
190
engine/src/Components/GameObject.cpp
Normal file
190
engine/src/Components/GameObject.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
#include "Components/GameObject.h"
|
||||
#include "Components/TransformComponent.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
|
||||
GameObject::ID GameObject::s_nextID = 1;
|
||||
|
||||
GameObject::GameObject()
|
||||
: m_name("GameObject") {
|
||||
m_id = s_nextID++;
|
||||
m_transform = new TransformComponent();
|
||||
m_transform->m_gameObject = this;
|
||||
}
|
||||
|
||||
GameObject::GameObject(const std::string& name)
|
||||
: m_name(name) {
|
||||
m_id = s_nextID++;
|
||||
m_transform = new TransformComponent();
|
||||
m_transform->m_gameObject = this;
|
||||
}
|
||||
|
||||
GameObject::~GameObject() {
|
||||
if (m_transform) {
|
||||
delete m_transform;
|
||||
m_transform = nullptr;
|
||||
}
|
||||
m_components.clear();
|
||||
}
|
||||
|
||||
std::unordered_map<GameObject::ID, GameObject*>& GameObject::GetGlobalRegistry() {
|
||||
static std::unordered_map<ID, GameObject*> registry;
|
||||
return registry;
|
||||
}
|
||||
|
||||
void GameObject::SetParent(GameObject* parent) {
|
||||
SetParent(parent, true);
|
||||
}
|
||||
|
||||
void GameObject::SetParent(GameObject* parent, bool worldPositionStays) {
|
||||
if (m_parent == parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
Math::Vector3 worldPos = worldPositionStays ? GetTransform()->GetPosition() : GetTransform()->GetLocalPosition();
|
||||
Math::Quaternion worldRot = worldPositionStays ? GetTransform()->GetRotation() : GetTransform()->GetLocalRotation();
|
||||
Math::Vector3 worldScale = worldPositionStays ? GetTransform()->GetScale() : GetTransform()->GetLocalScale();
|
||||
|
||||
if (m_parent) {
|
||||
auto& siblings = m_parent->m_children;
|
||||
siblings.erase(std::remove(siblings.begin(), siblings.end(), this), siblings.end());
|
||||
}
|
||||
|
||||
m_parent = parent;
|
||||
|
||||
if (m_parent) {
|
||||
m_parent->m_children.push_back(this);
|
||||
}
|
||||
|
||||
if (worldPositionStays) {
|
||||
GetTransform()->SetPosition(worldPos);
|
||||
GetTransform()->SetRotation(worldRot);
|
||||
GetTransform()->SetScale(worldScale);
|
||||
}
|
||||
|
||||
GetTransform()->SetDirty();
|
||||
}
|
||||
|
||||
GameObject* GameObject::GetChild(size_t index) const {
|
||||
if (index < m_children.size()) {
|
||||
return m_children[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<GameObject*> GameObject::GetChildren() const {
|
||||
return m_children;
|
||||
}
|
||||
|
||||
void GameObject::DetachChildren() {
|
||||
for (auto* child : m_children) {
|
||||
if (child) {
|
||||
child->m_parent = nullptr;
|
||||
}
|
||||
}
|
||||
m_children.clear();
|
||||
}
|
||||
|
||||
void GameObject::SetActive(bool active) {
|
||||
if (m_activeSelf != active) {
|
||||
m_activeSelf = active;
|
||||
if (m_parent == nullptr || m_parent->IsActiveInHierarchy()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GameObject::IsActiveInHierarchy() const {
|
||||
if (!m_activeSelf) {
|
||||
return false;
|
||||
}
|
||||
if (m_parent) {
|
||||
return m_parent->IsActiveInHierarchy();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
GameObject* GameObject::Find(const std::string& name) {
|
||||
auto& registry = GetGlobalRegistry();
|
||||
for (auto& pair : registry) {
|
||||
if (pair.second->GetName() == name) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<GameObject*> GameObject::FindObjectsOfType() {
|
||||
auto& registry = GetGlobalRegistry();
|
||||
std::vector<GameObject*> result;
|
||||
for (auto& pair : registry) {
|
||||
result.push_back(pair.second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<GameObject*> GameObject::FindGameObjectsWithTag(const std::string& tag) {
|
||||
auto& registry = GetGlobalRegistry();
|
||||
std::vector<GameObject*> result;
|
||||
for (auto& pair : registry) {
|
||||
if (pair.second->GetName() == tag) {
|
||||
result.push_back(pair.second);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void GameObject::Awake() {
|
||||
for (auto& comp : m_components) {
|
||||
comp->Awake();
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::Start() {
|
||||
for (auto& comp : m_components) {
|
||||
if (comp->IsEnabled()) {
|
||||
comp->Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::Update(float deltaTime) {
|
||||
for (auto& comp : m_components) {
|
||||
if (comp->IsEnabled()) {
|
||||
comp->Update(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::FixedUpdate() {
|
||||
for (auto& comp : m_components) {
|
||||
if (comp->IsEnabled()) {
|
||||
comp->FixedUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::LateUpdate(float deltaTime) {
|
||||
for (auto& comp : m_components) {
|
||||
if (comp->IsEnabled()) {
|
||||
comp->LateUpdate(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::OnDestroy() {
|
||||
for (auto& comp : m_components) {
|
||||
comp->OnDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::Destroy() {
|
||||
OnDestroy();
|
||||
if (m_scene) {
|
||||
m_scene->DestroyGameObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Components
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user