Fixed damageable triggers rendering the wrong side in rotated areas
This commit is contained in:
parent
ab38205611
commit
57451e231d
|
@ -1,6 +1,8 @@
|
|||
#include "CDamageableTriggerExtra.h"
|
||||
#include "Core/Render/CDrawUtil.h"
|
||||
#include "Core/Render/CRenderer.h"
|
||||
#include <Common/Assert.h>
|
||||
#include <Math/MathUtil.h>
|
||||
|
||||
CDamageableTriggerExtra::CDamageableTriggerExtra(CScriptObject *pInstance, CScene *pScene, CScriptNode *pParent)
|
||||
: CScriptExtra(pInstance, pScene, pParent)
|
||||
|
@ -38,7 +40,7 @@ CDamageableTriggerExtra::~CDamageableTriggerExtra()
|
|||
|
||||
void CDamageableTriggerExtra::CreateMaterial()
|
||||
{
|
||||
if (mpMat) delete mpMat;
|
||||
ASSERT(!mpMat);
|
||||
mpMat = new CMaterial(mGame, ePosition | eNormal | eTex0);
|
||||
|
||||
// Most values/TEV setup were found from the executable + from graphics debuggers
|
||||
|
@ -129,6 +131,49 @@ void CDamageableTriggerExtra::UpdatePlaneTransform()
|
|||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
CDamageableTriggerExtra::ERenderSide CDamageableTriggerExtra::RenderSideForDirection(const CVector3f& rkDir)
|
||||
{
|
||||
// Get the index of the largest XYZ component
|
||||
CVector3f AbsDir(Math::Abs(rkDir.X), Math::Abs(rkDir.Y), Math::Abs(rkDir.Z));
|
||||
u32 Max = (AbsDir.X > AbsDir.Y ? 0 : 1);
|
||||
Max = (AbsDir[Max] > AbsDir.Z ? Max : 2);
|
||||
|
||||
// Check whether the direction is positive or negative. If the absolute value of the component matches the input one, then it's positive.
|
||||
bool Positive = (rkDir[Max] == AbsDir[Max]);
|
||||
|
||||
// Return corresponding side for direction
|
||||
if (Max == 0) return (Positive ? eEast : eWest);
|
||||
else if (Max == 1) return (Positive ? eNorth : eSouth);
|
||||
else if (Max == 2) return (Positive ? eUp : eDown);
|
||||
|
||||
return eNoRender;
|
||||
}
|
||||
|
||||
CDamageableTriggerExtra::ERenderSide CDamageableTriggerExtra::TransformRenderSide(ERenderSide Side)
|
||||
{
|
||||
// DamageableTrigger has a convenience feature implemented that changes the
|
||||
// render side when the area's been rotated, so we need to replicate it here.
|
||||
CQuaternion AreaRotation = mpScriptNode->Instance()->Area()->Transform().ExtractRotation();
|
||||
|
||||
switch (Side)
|
||||
{
|
||||
case eNorth:
|
||||
return RenderSideForDirection(AreaRotation.YAxis());
|
||||
case eSouth:
|
||||
return RenderSideForDirection(-AreaRotation.YAxis());
|
||||
case eWest:
|
||||
return RenderSideForDirection(-AreaRotation.XAxis());
|
||||
case eEast:
|
||||
return RenderSideForDirection(AreaRotation.XAxis());
|
||||
case eUp:
|
||||
return RenderSideForDirection(AreaRotation.ZAxis());
|
||||
case eDown:
|
||||
return RenderSideForDirection(-AreaRotation.ZAxis());
|
||||
default:
|
||||
return eNoRender;
|
||||
}
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::OnTransformed()
|
||||
{
|
||||
mPlaneSize = mpSizeProp->Get();
|
||||
|
@ -139,7 +184,7 @@ void CDamageableTriggerExtra::PropertyModified(IProperty *pProperty)
|
|||
{
|
||||
if (pProperty == mpRenderSideProp)
|
||||
{
|
||||
mRenderSide = (ERenderSide) mpRenderSideProp->Get();
|
||||
mRenderSide = TransformRenderSide( (ERenderSide) mpRenderSideProp->Get() );
|
||||
UpdatePlaneTransform();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ public:
|
|||
~CDamageableTriggerExtra();
|
||||
void CreateMaterial();
|
||||
void UpdatePlaneTransform();
|
||||
ERenderSide RenderSideForDirection(const CVector3f& rkDir);
|
||||
ERenderSide TransformRenderSide(ERenderSide Side);
|
||||
void OnTransformed();
|
||||
void PropertyModified(IProperty *pProperty);
|
||||
bool ShouldDrawNormalAssets();
|
||||
|
|
|
@ -185,12 +185,6 @@ CVector4f CMatrix4f::operator*(const CVector4f& rkVec) const
|
|||
return out;
|
||||
}
|
||||
|
||||
CQuaternion CMatrix4f::operator*(const CQuaternion& rkQuat) const
|
||||
{
|
||||
// todo: there's probably a faster way to do this. (mirrored in CTransform4f and CQuaternion)
|
||||
return CQuaternion::FromRotationMatrix(Inverse().Transpose()) * rkQuat;
|
||||
}
|
||||
|
||||
CMatrix4f CMatrix4f::operator*(const CTransform4f& rkMtx) const
|
||||
{
|
||||
// CTransform4f is a 3x4 matrix with an implicit fourth row of {0, 0, 0, 1}
|
||||
|
|
|
@ -144,13 +144,12 @@ void CQuaternion::operator *= (const CQuaternion& rkOther)
|
|||
*this = *this * rkOther;
|
||||
}
|
||||
|
||||
CQuaternion CQuaternion::operator*(const CMatrix4f& rkMtx) const
|
||||
CQuaternion CQuaternion::operator*(const CTransform4f& rkMtx) const
|
||||
{
|
||||
// todo: there's probably a faster way to do this. (mirrored in CMatrix4f and CTransform4f)
|
||||
return *this * CQuaternion::FromRotationMatrix(rkMtx.Inverse().Transpose());
|
||||
return *this * rkMtx.ExtractRotation();
|
||||
}
|
||||
|
||||
void CQuaternion::operator *= (const CMatrix4f& rkMtx)
|
||||
void CQuaternion::operator *= (const CTransform4f& rkMtx)
|
||||
{
|
||||
*this = *this * rkMtx;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ public:
|
|||
CVector3f operator*(const CVector3f& rkVec) const;
|
||||
CQuaternion operator*(const CQuaternion& rkOther) const;
|
||||
void operator *= (const CQuaternion& rkOther);
|
||||
CQuaternion operator*(const CMatrix4f& rkMtx) const;
|
||||
void operator *= (const CMatrix4f& rkMtx);
|
||||
CQuaternion operator*(const CTransform4f& rkMtx) const;
|
||||
void operator *= (const CTransform4f& rkMtx);
|
||||
|
||||
// Static
|
||||
static CQuaternion FromEuler(CVector3f Euler);
|
||||
|
|
|
@ -186,11 +186,15 @@ CTransform4f CTransform4f::RotationOnly() const
|
|||
|
||||
CVector3f CTransform4f::ExtractTranslation() const
|
||||
{
|
||||
CVector3f Test = *this * CVector3f::skZero;
|
||||
Test = Test;
|
||||
return CVector3f(m[0][3], m[1][3], m[2][3]);
|
||||
}
|
||||
|
||||
CQuaternion CTransform4f::ExtractRotation() const
|
||||
{
|
||||
// todo: there's probably a faster way to do this...
|
||||
return CQuaternion::FromRotationMatrix(Inverse().Transpose());
|
||||
}
|
||||
|
||||
// ************ OPERATORS ************
|
||||
float* CTransform4f::operator[](long Index)
|
||||
{
|
||||
|
@ -223,8 +227,7 @@ CVector4f CTransform4f::operator*(const CVector4f& rkVec) const
|
|||
|
||||
CQuaternion CTransform4f::operator*(const CQuaternion& rkQuat) const
|
||||
{
|
||||
// todo: there's probably a faster way to do this. (mirrored in CMatrix4f and CQuaternion)
|
||||
return CQuaternion::FromRotationMatrix(Inverse().Transpose()) * rkQuat;
|
||||
return ExtractRotation() * rkQuat;
|
||||
}
|
||||
|
||||
CTransform4f CTransform4f::operator*(const CTransform4f& rkMtx) const
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
CTransform4f RotationOnly() const;
|
||||
|
||||
CVector3f ExtractTranslation() const;
|
||||
CQuaternion ExtractRotation() const;
|
||||
|
||||
// Static
|
||||
static CTransform4f TranslationMatrix(CVector3f Translation);
|
||||
|
|
Loading…
Reference in New Issue