Changeset View
Changeset View
Standalone View
Standalone View
source/graphics/Unit.cpp
Show All 25 Lines | |||||
#include "SkeletonAnimDef.h" | #include "SkeletonAnimDef.h" | ||||
#include "UnitAnimation.h" | #include "UnitAnimation.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
CUnit::CUnit(CObjectManager& objectManager, const CActorDef& actor, uint32_t seed) | CUnit::CUnit(CObjectManager& objectManager, const CActorDef& actor, uint32_t seed) | ||||
: m_ID(INVALID_ENTITY), m_ObjectManager(objectManager), m_Actor(actor), m_Seed(seed), m_Animation(nullptr) | : m_ID(INVALID_ENTITY), m_ObjectManager(objectManager), m_Actor(actor), m_Seed(seed), m_Animation(nullptr) | ||||
{ | { | ||||
m_Model = m_Models.end(); | |||||
} | } | ||||
CUnit::~CUnit() | CUnit::~CUnit() | ||||
{ | { | ||||
delete m_Animation; | |||||
delete m_Model; | |||||
} | } | ||||
CUnit* CUnit::Create(const CStrW& actorName, uint32_t seed, const std::set<CStr>& selections, CObjectManager& objectManager) | CUnit* CUnit::Create(const CStrW& actorName, uint32_t seed, const std::set<CStr>& selections, CObjectManager& objectManager) | ||||
{ | { | ||||
auto [success, actor] = objectManager.FindActorDef(actorName); | auto [success, actor] = objectManager.FindActorDef(actorName); | ||||
ENSURE(success); | ENSURE(success); | ||||
CUnit* unit = new CUnit(objectManager, actor, seed); | CUnit* unit = new CUnit(objectManager, actor, seed); | ||||
unit->SetActorSelections(selections); // Calls ReloadObject(). | unit->SetActorSelections(selections); // Calls ReloadObject(). | ||||
if (!unit->m_Model) | if (unit->m_Model == unit->m_Models.end()) | ||||
{ | { | ||||
delete unit; | delete unit; | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
return unit; | return unit; | ||||
} | } | ||||
void CUnit::UpdateModel(float frameTime) | void CUnit::UpdateModel(float frameTime) | ||||
{ | { | ||||
if (m_Animation) | if (m_Animation) | ||||
m_Animation->Update(frameTime*1000.0f); | m_Animation->Update(frameTime*1000.0f); | ||||
} | } | ||||
void CUnit::UpdateQualityLevel(u8 quality) | |||||
{ | |||||
if (quality == m_QualityLevel) | |||||
return; | |||||
u8 newIndex = GetIndexForQuality(quality); | |||||
u8 oldIndex = GetIndexForQuality(m_QualityLevel); | |||||
m_QualityLevel = quality; | |||||
if (newIndex == oldIndex) | |||||
Stan: When does that happen? | |||||
Done Inline ActionsQuality is 0-255 but there are at most 5 levels, so there's a lot of cases where we need to change nothing. wraitii: Quality is 0-255 but there are at most 5 levels, so there's a lot of cases where we need to… | |||||
return; | |||||
// Update the current object & model and update. | |||||
m_Object = m_Objects[newIndex]; | |||||
m_Model = m_Models.begin() + newIndex; | |||||
UpdateCurrentModel(m_Models[oldIndex]); | |||||
} | |||||
void CUnit::SetID(entity_id_t id) | void CUnit::SetID(entity_id_t id) | ||||
{ | { | ||||
m_ID = id; | m_ID = id; | ||||
if (m_Animation) | if (m_Animation) | ||||
m_Animation->SetEntityID(id); | m_Animation->SetEntityID(id); | ||||
} | } | ||||
void CUnit::SetEntitySelection(const CStr& key, const CStr& selection) | void CUnit::SetEntitySelection(const CStr& key, const CStr& selection) | ||||
Show All 30 Lines | void CUnit::ReloadObject() | ||||
selections.push_back(entitySelections); | selections.push_back(entitySelections); | ||||
selections.push_back(m_ActorSelections); | selections.push_back(m_ActorSelections); | ||||
// randomly select any remain selections necessary to completely identify a variation (e.g., the new selection | // randomly select any remain selections necessary to completely identify a variation (e.g., the new selection | ||||
// made might define some additional props that require a random variant choice). Also, FindObjectVariation | // made might define some additional props that require a random variant choice). Also, FindObjectVariation | ||||
// expects the selectors passed to it to be complete. | // expects the selectors passed to it to be complete. | ||||
// see http://trac.wildfiregames.com/ticket/979 | // see http://trac.wildfiregames.com/ticket/979 | ||||
// If these selections give a different object, change this unit to use it | |||||
// Use the entity ID as randomization seed (same as when the unit was first created) | // Use the entity ID as randomization seed (same as when the unit was first created) | ||||
CObjectEntry* newObject = m_ObjectManager.FindObjectVariation(&m_Actor, selections, m_Seed); | std::vector<CObjectEntry*> objects = m_ObjectManager.FindObjectVariations(m_Actor, selections, m_Seed); | ||||
if (!newObject) | |||||
if (objects.empty()) | |||||
{ | { | ||||
LOGERROR("Error loading object variation (actor: %s)", m_Actor.GetPathname().string8()); | LOGERROR("Error loading object variations (actor: %s)", m_Actor.GetPathname().string8()); | ||||
// Don't delete the unit, don't override our current (valid) state. | // Don't delete the unit, don't override our current (valid) state. | ||||
return; | return; | ||||
} | } | ||||
if (!m_Object) | // If these selections give the same objects, do nothing. | ||||
if (objects == m_Objects) | |||||
return; | |||||
// Otherwise, switch the objects, the current object, and reload. | |||||
m_Objects = objects; | |||||
std::unique_ptr<CModelAbstract> oldModel = m_Model != m_Models.end() ? std::move(*m_Model) : std::unique_ptr<CModelAbstract>(); | |||||
// Re-init the models with null pointers. | |||||
m_Models.clear(); | |||||
m_Models.resize(m_Objects.size()); | |||||
u8 i = GetIndexForQuality(m_QualityLevel); | |||||
m_Object = m_Objects[i]; | |||||
m_Model = m_Models.begin() + i; | |||||
UpdateCurrentModel(oldModel); | |||||
} | |||||
u8 CUnit::GetIndexForQuality(u8 quality) | |||||
{ | { | ||||
m_Object = newObject; | for (size_t i = 0; i < m_Objects.size(); ++i) | ||||
m_Model = newObject->m_Model->Clone(); | if (m_Objects[i]->m_Base->m_QualityLevel >= quality) | ||||
if (m_Model->ToCModel()) | return static_cast<u8>(i); | ||||
Not Done Inline Actionsstatic_cast. Gravité Code Description Projet Fichier Ligne État de la suppression Avertissement C4267 'return' : conversion de 'size_t' en 'u8', perte possible de données graphics c:\dev\trunk\source\graphics\unit.cpp 156 Stan: static_cast.
```
Gravité Code Description Projet Fichier Ligne État de la suppression… | |||||
m_Animation = new CUnitAnimation(m_ID, m_Model->ToCModel(), m_Object); | return m_Objects.size() - 1; | ||||
} | } | ||||
else if (m_Object && newObject != m_Object) | |||||
void CUnit::UpdateCurrentModel(const std::unique_ptr<CModelAbstract>& oldModel) | |||||
{ | |||||
ENSURE(m_Model != m_Models.end()); | |||||
CModelAbstract* model = m_Model->get(); | |||||
if (!model) | |||||
{ | { | ||||
// Clone the new object's base (non-instance) model | *m_Model = std::unique_ptr<CModelAbstract>(m_Object->m_Model->Clone()); | ||||
CModelAbstract* newModel = newObject->m_Model->Clone(); | model = m_Model->get(); | ||||
} | |||||
// Nothing to do if the model was already loaded and is already selected. | |||||
else if (model == oldModel.get()) | |||||
return; | |||||
// Copy data from the current model, if relevant. | |||||
if (oldModel) | |||||
{ | |||||
// Copy the old instance-specific settings from the old model to the new instance | // Copy the old instance-specific settings from the old model to the new instance | ||||
newModel->SetTransform(m_Model->GetTransform()); | model->SetTransform(oldModel->GetTransform()); | ||||
newModel->SetPlayerID(m_Model->GetPlayerID()); | model->SetPlayerID(oldModel->GetPlayerID()); | ||||
if (newModel->ToCModel() && m_Model->ToCModel()) | if (model->ToCModel() && oldModel->ToCModel()) | ||||
{ | { | ||||
newModel->ToCModel()->CopyAnimationFrom(m_Model->ToCModel()); | model->ToCModel()->CopyAnimationFrom(oldModel->ToCModel()); | ||||
// Copy flags that belong to this model instance (not those defined by the actor XML) | // Copy flags that belong to this model instance (not those defined by the actor XML) | ||||
int instanceFlags = (MODELFLAG_SILHOUETTE_DISPLAY|MODELFLAG_SILHOUETTE_OCCLUDER|MODELFLAG_IGNORE_LOS) & m_Model->ToCModel()->GetFlags(); | int instanceFlags = (MODELFLAG_SILHOUETTE_DISPLAY|MODELFLAG_SILHOUETTE_OCCLUDER|MODELFLAG_IGNORE_LOS) & oldModel->ToCModel()->GetFlags(); | ||||
newModel->ToCModel()->AddFlagsRec(instanceFlags); | model->ToCModel()->AddFlagsRec(instanceFlags); | ||||
} | |||||
} | } | ||||
delete m_Model; | if (model->ToCModel()) | ||||
m_Model = newModel; | |||||
m_Object = newObject; | |||||
if (m_Model->ToCModel()) | |||||
{ | { | ||||
if (m_Animation) | if (m_Animation) | ||||
m_Animation->ReloadUnit(m_Model->ToCModel(), m_Object); // TODO: maybe this should try to preserve animation state? | m_Animation->ReloadUnit(model->ToCModel(), m_Object); // TODO: maybe this should try to preserve animation state? | ||||
else | else | ||||
m_Animation = new CUnitAnimation(m_ID, m_Model->ToCModel(), m_Object); | m_Animation = std::make_unique<CUnitAnimation>(m_ID, model->ToCModel(), m_Object); | ||||
} | } | ||||
else | else | ||||
{ | m_Animation.reset(); | ||||
SAFE_DELETE(m_Animation); | |||||
} | |||||
} | |||||
} | } |
Wildfire Games · Phabricator
When does that happen?