SceneNode::SceneNode(SceneNode* pParent,
const D3DXVECTOR3& position,
const D3DXVECTOR3& rotation,
const D3DXVECTOR3& scale) :
m_bTransparent(false),
m_bVisible(true),
m_pParent(nullptr),
m_iID(0)
{
m_RelativeTranslation = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_RelativeRotation = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_RelativeScale = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
D3DXMatrixIdentity(&m_AbsoluteTransformation);
D3DXMatrixIdentity(&m_RelativeTransformation);
UpdateAbsoluteTransformation();
}
SceneNode::~SceneNode()
{
RemoveAll();
}
unsigned int SceneNode::GetID()
{
return m_iID;
}
void SceneNode::SetID(unsigned int iID)
{
m_iID = iID;
}
bool SceneNode::IsVisible()
{
return m_bVisible;
}
void SceneNode::SetVisible(bool bVisible)
{
m_bVisible = bVisible;
}
bool SceneNode::OnPreRender(float fTimeSinceLastFrame)
{
UpdateAbsoluteTransformation();
SCENE_MANAGER->PushAndSetMatrix(m_AbsoluteTransformation);
return true;
}
bool SceneNode::OnPostRender(float fTimeSinceLastFrame)
{
SCENE_MANAGER->PopMatrix();
return true;
}
D3DXVECTOR3& SceneNode::GetPosition()
{
return m_RelativeTranslation;
}
void SceneNode::SetPosition(const D3DXVECTOR3& position)
{
m_RelativeTranslation = position;
UpdateRelativeTransformation();
}
void SceneNode::SetPosition(float x, float y, float z)
{
m_RelativeTranslation = D3DXVECTOR3(x, y, z);
UpdateRelativeTransformation();
}
bool SceneNode::IsTransparent()
{
return m_bTransparent;
}
void SceneNode::SetTransparent(bool bTransparent)
{
m_bTransparent = bTransparent;
}
void SceneNode::UpdateRelativeTransformation()
{
D3DXMATRIX matTrans;
D3DXMatrixTranslation(&matTrans, m_RelativeTranslation.x, m_RelativeTranslation.y, m_RelativeTranslation.z);
D3DXMATRIX matRotX;
D3DXMatrixRotationX(&matRotX, m_RelativeRotation.x);
D3DXMATRIX matRotY;
D3DXMatrixRotationY(&matRotY, m_RelativeRotation.y);
D3DXMATRIX matRotZ;
D3DXMatrixRotationZ(&matRotZ, m_RelativeRotation.z);
D3DXMATRIX matRotation = matRotX * matRotY * matRotZ;
D3DXMATRIX matScale;
D3DXMatrixScaling(&matScale, m_RelativeScale.x, m_RelativeScale.y, m_RelativeScale.z);
// Ordre de la multiplication : S*R*T
m_RelativeTransformation = matScale * matRotation * matTrans;
}
void SceneNode::UpdateAbsoluteTransformation()
{
if (m_pParent)
{
D3DXMATRIX AbsoluteTrans = m_pParent->GetAbsoluteTransformation();
D3DXMATRIX RelativeTrans = GetRelativeTransformation();
D3DXMatrixMultiply(&m_AbsoluteTransformation, &AbsoluteTrans, &RelativeTrans);
}
else
{
m_AbsoluteTransformation = GetRelativeTransformation();
}
}
D3DMATRIX& SceneNode::GetAbsoluteTransformation()
{
UpdateAbsoluteTransformation();
return m_AbsoluteTransformation;
}
D3DXMATRIX& SceneNode::GetRelativeTransformation()
{
UpdateRelativeTransformation();
return m_RelativeTransformation;
}
std::string& SceneNode::GetName()
{
return m_sName;
}
void SceneNode::SetName(const std::string& sName)
{
m_sName = sName;
}
D3DXVECTOR3& SceneNode::GetScale()
{
return m_RelativeScale;
}
void SceneNode::SetScale(float x, float y, float z)
{
m_RelativeScale = D3DXVECTOR3(x, y, z);
UpdateRelativeTransformation();
}
D3DXVECTOR3& SceneNode::GetRotation()
{
return m_RelativeRotation;
}
void SceneNode::SetRotation(float x, float y, float z)
{
m_RelativeRotation = D3DXVECTOR3(x, y, z);
UpdateRelativeTransformation();
}
void SceneNode::AddChild(SceneNode* pChild)
{
if (pChild && (pChild != this))
{
pChild->RemoveParent();
m_children.push_back(pChild);
pChild->SetParent(this);
MeshSceneNode* pChildSceneNode = dynamic_cast<MeshSceneNode*>(pChild);
if (typeid(pChildSceneNode) == typeid(MeshSceneNode*))
{
SCENE_MANAGER->AddSceneNode(pChildSceneNode);
}
}
}
void SceneNode::RemoveChild(SceneNode* pChild)
{
for (auto it = m_children.begin(); it != m_children.end(); it++)
{
SceneNode* pCurrentChild = *it;
if (pCurrentChild == pChild)
{
pCurrentChild->RemoveParent();
m_children.erase(it);
}
}
}
void SceneNode::RemoveAll()
{
for (auto it = m_children.begin(); it != m_children.end(); it++)
{
SceneNode* pCurrentChild = *it;
m_children.erase(it);
}
m_children.clear();
}
void SceneNode::SetParent(SceneNode* pSceneNode)
{
Remove();
m_pParent = pSceneNode;
}
SceneNode* SceneNode::GetParent()
{
return m_pParent;
}
void SceneNode::RemoveParent()
{
m_pParent = nullptr;
}
void SceneNode::Remove()
{
if (m_pParent)
{
m_pParent->RemoveChild(this);
}
}
std::vector<SceneNode*> SceneNode::GetChildren()
{
return m_children;
}
D3DXVECTOR3 SceneNode::GetAbsolutePosition()
{
D3DXVECTOR3 absolutePosition;
absolutePosition.x = m_AbsoluteTransformation._12;
absolutePosition.y = m_AbsoluteTransformation._13;
absolutePosition.z = m_AbsoluteTransformation._14;
return absolutePosition;
}