| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- // ----------------------------------------------------------------
- // From Game Programming in C++ by Sanjay Madhav
- // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
- //
- // Released under the BSD License
- // See LICENSE in root directory for full details.
- // ----------------------------------------------------------------
- #include "Actor.h"
- #include "Game.h"
- #include "Component.h"
- #include <algorithm>
- Actor::Actor(Game* game)
- :mState(EActive)
- ,mPosition(Vector3::Zero)
- ,mRotation(Quaternion::Identity)
- ,mScale(1.0f)
- ,mGame(game)
- ,mRecomputeWorldTransform(true)
- {
- mGame->AddActor(this);
- }
- Actor::~Actor()
- {
- mGame->RemoveActor(this);
- // Need to delete components
- // Because ~Component calls RemoveComponent, need a different style loop
- while (!mComponents.empty())
- {
- delete mComponents.back();
- }
- }
- void Actor::Update(float deltaTime)
- {
- if (mState == EActive)
- {
- ComputeWorldTransform();
- UpdateComponents(deltaTime);
- UpdateActor(deltaTime);
- ComputeWorldTransform();
- }
- }
- void Actor::UpdateComponents(float deltaTime)
- {
- for (auto comp : mComponents)
- {
- comp->Update(deltaTime);
- }
- }
- void Actor::UpdateActor(float deltaTime)
- {
- }
- void Actor::ProcessInput(const uint8_t* keyState)
- {
- if (mState == EActive)
- {
- // First process input for components
- for (auto comp : mComponents)
- {
- comp->ProcessInput(keyState);
- }
- ActorInput(keyState);
- }
- }
- void Actor::ActorInput(const uint8_t* keyState)
- {
- }
- void Actor::RotateToNewForward(const Vector3& forward)
- {
- // Figure out difference between original (unit x) and new
- float dot = Vector3::Dot(Vector3::UnitX, forward);
- float angle = Math::Acos(dot);
- // Facing down X
- if (dot > 0.9999f)
- {
- SetRotation(Quaternion::Identity);
- }
- // Facing down -X
- else if (dot < -0.9999f)
- {
- SetRotation(Quaternion(Vector3::UnitZ, Math::Pi));
- }
- else
- {
- // Rotate about axis from cross product
- Vector3 axis = Vector3::Cross(Vector3::UnitX, forward);
- axis.Normalize();
- SetRotation(Quaternion(axis, angle));
- }
- }
- void Actor::ComputeWorldTransform()
- {
- if (mRecomputeWorldTransform)
- {
- mRecomputeWorldTransform = false;
- // Scale, then rotate, then translate
- mWorldTransform = Matrix4::CreateScale(mScale);
- mWorldTransform *= Matrix4::CreateFromQuaternion(mRotation);
- mWorldTransform *= Matrix4::CreateTranslation(mPosition);
- // Inform components world transform updated
- for (auto comp : mComponents)
- {
- comp->OnUpdateWorldTransform();
- }
- }
- }
- void Actor::AddComponent(Component* component)
- {
- // Find the insertion point in the sorted vector
- // (The first element with a order higher than me)
- int myOrder = component->GetUpdateOrder();
- auto iter = mComponents.begin();
- for (;
- iter != mComponents.end();
- ++iter)
- {
- if (myOrder < (*iter)->GetUpdateOrder())
- {
- break;
- }
- }
- // Inserts element before position of iterator
- mComponents.insert(iter, component);
- }
- void Actor::RemoveComponent(Component* component)
- {
- auto iter = std::find(mComponents.begin(), mComponents.end(), component);
- if (iter != mComponents.end())
- {
- mComponents.erase(iter);
- }
- }
|