Set up CCamera, CLight, and CSceneNode to use mutable members for caching; modified CSceneNode to allow subclasses to change how transform is calculated
This commit is contained in:
parent
c260e547c9
commit
0da183b161
224
Core/CCamera.cpp
224
Core/CCamera.cpp
|
@ -13,36 +13,36 @@ CCamera::CCamera()
|
||||||
mYaw = -Math::skHalfPi;
|
mYaw = -Math::skHalfPi;
|
||||||
mPitch = 0.0f;
|
mPitch = 0.0f;
|
||||||
SetOrbit(CVector3f(0), 5.f);
|
SetOrbit(CVector3f(0), 5.f);
|
||||||
Update();
|
|
||||||
|
|
||||||
mMoveSpeed = 1.f;
|
mMoveSpeed = 1.f;
|
||||||
mLookSpeed = 1.f;
|
mLookSpeed = 1.f;
|
||||||
mViewOutdated = true;
|
mTransformDirty = true;
|
||||||
mProjectionOutdated = true;
|
mViewDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mProjectionDirty = true;
|
||||||
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCamera::CCamera(CVector3f Position, CVector3f /*Target*/)
|
CCamera::CCamera(CVector3f Position, CVector3f /*Target*/)
|
||||||
{
|
{
|
||||||
// todo: make it actually look at the target!
|
// todo: make it actually look at the target!
|
||||||
|
// don't actually use this constructor, it's unfinished and won't work properly
|
||||||
mMode = eFreeCamera;
|
mMode = eFreeCamera;
|
||||||
mMoveSpeed = 1.f;
|
mMoveSpeed = 1.f;
|
||||||
mLookSpeed = 1.f;
|
mLookSpeed = 1.f;
|
||||||
mPosition = Position;
|
mPosition = Position;
|
||||||
mYaw = -Math::skHalfPi;
|
mYaw = -Math::skHalfPi;
|
||||||
mPitch = 0.0f;
|
mPitch = 0.0f;
|
||||||
Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::Pan(float XAmount, float YAmount)
|
void CCamera::Pan(float XAmount, float YAmount)
|
||||||
{
|
{
|
||||||
if (mMode == eFreeCamera)
|
if (mMode == eFreeCamera)
|
||||||
{
|
{
|
||||||
Update();
|
|
||||||
mPosition += mRightVector * (XAmount * mMoveSpeed);
|
mPosition += mRightVector * (XAmount * mMoveSpeed);
|
||||||
mPosition += mUpVector * (YAmount * mMoveSpeed);
|
mPosition += mUpVector * (YAmount * mMoveSpeed);
|
||||||
mViewOutdated = true;
|
mTransformDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mViewDirty = true;
|
||||||
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -53,24 +53,26 @@ void CCamera::Rotate(float XAmount, float YAmount)
|
||||||
{
|
{
|
||||||
mYaw -= (XAmount * mLookSpeed * 0.3f);
|
mYaw -= (XAmount * mLookSpeed * 0.3f);
|
||||||
mPitch -= (YAmount * mLookSpeed * 0.3f);
|
mPitch -= (YAmount * mLookSpeed * 0.3f);
|
||||||
|
ValidatePitch();
|
||||||
|
|
||||||
mViewOutdated = true;
|
mTransformDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mViewDirty = true;
|
||||||
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::Zoom(float Amount)
|
void CCamera::Zoom(float Amount)
|
||||||
{
|
{
|
||||||
if (mMode == eFreeCamera)
|
if (mMode == eFreeCamera)
|
||||||
{
|
|
||||||
Update();
|
|
||||||
mPosition += mDirection * (Amount * mMoveSpeed);
|
mPosition += mDirection * (Amount * mMoveSpeed);
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mOrbitDistance -= Amount * mMoveSpeed;
|
mOrbitDistance -= Amount * mMoveSpeed;
|
||||||
|
mTransformDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
mViewOutdated = true;
|
mViewDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::Snap(CVector3f Position)
|
void CCamera::Snap(CVector3f Position)
|
||||||
|
@ -78,9 +80,9 @@ void CCamera::Snap(CVector3f Position)
|
||||||
mPosition = Position;
|
mPosition = Position;
|
||||||
mYaw = -Math::skHalfPi;
|
mYaw = -Math::skHalfPi;
|
||||||
mPitch = 0.0f;
|
mPitch = 0.0f;
|
||||||
mViewOutdated = true;
|
mTransformDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mViewDirty = true;
|
||||||
Update();
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::ProcessKeyInput(EKeyInputs KeyFlags, double DeltaTime)
|
void CCamera::ProcessKeyInput(EKeyInputs KeyFlags, double DeltaTime)
|
||||||
|
@ -117,7 +119,7 @@ void CCamera::ProcessMouseInput(EKeyInputs KeyFlags, EMouseInputs MouseFlags, fl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CRay CCamera::CastRay(CVector2f DeviceCoords)
|
CRay CCamera::CastRay(CVector2f DeviceCoords) const
|
||||||
{
|
{
|
||||||
CMatrix4f InverseVP = (ViewMatrix().Transpose() * ProjectionMatrix().Transpose()).Inverse();
|
CMatrix4f InverseVP = (ViewMatrix().Transpose() * ProjectionMatrix().Transpose()).Inverse();
|
||||||
|
|
||||||
|
@ -134,8 +136,11 @@ CRay CCamera::CastRay(CVector2f DeviceCoords)
|
||||||
void CCamera::SetMoveMode(ECameraMoveMode Mode)
|
void CCamera::SetMoveMode(ECameraMoveMode Mode)
|
||||||
{
|
{
|
||||||
mMode = Mode;
|
mMode = Mode;
|
||||||
mViewOutdated = true;
|
mViewDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mFrustumPlanesDirty = true;
|
||||||
|
|
||||||
|
if (mMode == eOrbitCamera)
|
||||||
|
mTransformDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::SetOrbit(const CVector3f& OrbitTarget, float Distance)
|
void CCamera::SetOrbit(const CVector3f& OrbitTarget, float Distance)
|
||||||
|
@ -145,24 +150,34 @@ void CCamera::SetOrbit(const CVector3f& OrbitTarget, float Distance)
|
||||||
|
|
||||||
if (mMode == eOrbitCamera)
|
if (mMode == eOrbitCamera)
|
||||||
{
|
{
|
||||||
mViewOutdated = true;
|
mTransformDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mViewDirty = true;
|
||||||
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::SetOrbit(const CAABox& OrbitTarget, float DistScale /*= 2.5f*/)
|
void CCamera::SetOrbit(const CAABox& OrbitTarget, float DistScale /*= 4.f*/)
|
||||||
{
|
{
|
||||||
CVector3f Min = OrbitTarget.Min();
|
CVector3f Min = OrbitTarget.Min();
|
||||||
CVector3f Max = OrbitTarget.Max();
|
CVector3f Max = OrbitTarget.Max();
|
||||||
|
|
||||||
mOrbitTarget = OrbitTarget.Center();
|
mOrbitTarget = OrbitTarget.Center();
|
||||||
mOrbitDistance = ((Max.x - Min.x) + (Max.y - Min.y) + (Max.z - Min.z)) / 3.f;
|
|
||||||
mOrbitDistance *= DistScale;
|
// Find largest extent
|
||||||
|
CVector3f Extent = (Max - Min) / 2.f;
|
||||||
|
float Dist = 0.f;
|
||||||
|
|
||||||
|
if (Extent.x >= Extent.y && Extent.x >= Extent.z) Dist = Extent.x;
|
||||||
|
else if (Extent.y >= Extent.x && Extent.y >= Extent.z) Dist = Extent.y;
|
||||||
|
else Dist = Extent.z;
|
||||||
|
|
||||||
|
mOrbitDistance = Dist * DistScale;
|
||||||
|
|
||||||
if (mMode == eOrbitCamera)
|
if (mMode == eOrbitCamera)
|
||||||
{
|
{
|
||||||
mViewOutdated = true;
|
mTransformDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mViewDirty = true;
|
||||||
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,12 +187,13 @@ void CCamera::SetOrbitDistance(float Distance)
|
||||||
|
|
||||||
if (mMode == eOrbitCamera)
|
if (mMode == eOrbitCamera)
|
||||||
{
|
{
|
||||||
mViewOutdated = true;
|
mTransformDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mViewDirty = true;
|
||||||
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::LoadMatrices()
|
void CCamera::LoadMatrices() const
|
||||||
{
|
{
|
||||||
CGraphics::sMVPBlock.ViewMatrix = ViewMatrix();
|
CGraphics::sMVPBlock.ViewMatrix = ViewMatrix();
|
||||||
CGraphics::sMVPBlock.ProjectionMatrix = ProjectionMatrix();
|
CGraphics::sMVPBlock.ProjectionMatrix = ProjectionMatrix();
|
||||||
|
@ -187,21 +203,25 @@ void CCamera::LoadMatrices()
|
||||||
// ************ GETTERS ************
|
// ************ GETTERS ************
|
||||||
CVector3f CCamera::Position() const
|
CVector3f CCamera::Position() const
|
||||||
{
|
{
|
||||||
|
UpdateTransform();
|
||||||
return mPosition;
|
return mPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f CCamera::Direction() const
|
CVector3f CCamera::Direction() const
|
||||||
{
|
{
|
||||||
|
UpdateTransform();
|
||||||
return mDirection;
|
return mDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f CCamera::UpVector() const
|
CVector3f CCamera::UpVector() const
|
||||||
{
|
{
|
||||||
|
UpdateTransform();
|
||||||
return mUpVector;
|
return mUpVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f CCamera::RightVector() const
|
CVector3f CCamera::RightVector() const
|
||||||
{
|
{
|
||||||
|
UpdateTransform();
|
||||||
return mRightVector;
|
return mRightVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,53 +245,36 @@ ECameraMoveMode CCamera::MoveMode() const
|
||||||
return mMode;
|
return mMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CMatrix4f& CCamera::ViewMatrix()
|
const CMatrix4f& CCamera::ViewMatrix() const
|
||||||
{
|
{
|
||||||
if (mViewOutdated)
|
UpdateView();
|
||||||
UpdateView();
|
return mViewMatrix;
|
||||||
|
|
||||||
return mCachedViewMatrix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CMatrix4f& CCamera::ProjectionMatrix()
|
const CMatrix4f& CCamera::ProjectionMatrix() const
|
||||||
{
|
{
|
||||||
if (mProjectionOutdated)
|
UpdateProjection();
|
||||||
UpdateProjection();
|
return mProjectionMatrix;
|
||||||
|
|
||||||
return mCachedProjectionMatrix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CFrustumPlanes& CCamera::FrustumPlanes()
|
const CFrustumPlanes& CCamera::FrustumPlanes() const
|
||||||
{
|
{
|
||||||
if (mFrustumPlanesOutdated)
|
UpdateFrustum();
|
||||||
UpdateFrustum();
|
return mFrustumPlanes;
|
||||||
|
|
||||||
return mCachedFrustumPlanes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ SETTERS ************
|
// ************ SETTERS ************
|
||||||
void CCamera::SetPosition(CVector3f Position)
|
|
||||||
{
|
|
||||||
mPosition = Position;
|
|
||||||
mViewOutdated = true;
|
|
||||||
mFrustumPlanesOutdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCamera::SetDirection(CVector3f Direction)
|
|
||||||
{
|
|
||||||
mDirection = Direction;
|
|
||||||
mViewOutdated = true;
|
|
||||||
mFrustumPlanesOutdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCamera::SetYaw(float Yaw)
|
void CCamera::SetYaw(float Yaw)
|
||||||
{
|
{
|
||||||
mYaw = Yaw;
|
mYaw = Yaw;
|
||||||
|
mTransformDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::SetPitch(float Pitch)
|
void CCamera::SetPitch(float Pitch)
|
||||||
{
|
{
|
||||||
mPitch = Pitch;
|
mPitch = Pitch;
|
||||||
|
ValidatePitch();
|
||||||
|
mTransformDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::SetMoveSpeed(float MoveSpeed)
|
void CCamera::SetMoveSpeed(float MoveSpeed)
|
||||||
|
@ -287,62 +290,81 @@ void CCamera::SetLookSpeed(float LookSpeed)
|
||||||
void CCamera::SetAspectRatio(float AspectRatio)
|
void CCamera::SetAspectRatio(float AspectRatio)
|
||||||
{
|
{
|
||||||
mAspectRatio = AspectRatio;
|
mAspectRatio = AspectRatio;
|
||||||
mProjectionOutdated = true;
|
mProjectionDirty = true;
|
||||||
mFrustumPlanesOutdated = true;
|
mFrustumPlanesDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ PRIVATE ************
|
// ************ PRIVATE ************
|
||||||
void CCamera::Update()
|
void CCamera::ValidatePitch()
|
||||||
{
|
{
|
||||||
// Update direction
|
// This function mainly just exists to ensure the camera doesn't flip upside down
|
||||||
if (mPitch > Math::skHalfPi) mPitch = Math::skHalfPi;
|
if (mPitch > Math::skHalfPi) mPitch = Math::skHalfPi;
|
||||||
if (mPitch < -Math::skHalfPi) mPitch = -Math::skHalfPi;
|
if (mPitch < -Math::skHalfPi) mPitch = -Math::skHalfPi;
|
||||||
|
|
||||||
mDirection = CVector3f(
|
|
||||||
cos(mPitch) * cos(mYaw),
|
|
||||||
cos(mPitch) * sin(mYaw),
|
|
||||||
sin(mPitch)
|
|
||||||
);
|
|
||||||
|
|
||||||
mRightVector = CVector3f(
|
|
||||||
cos(mYaw - Math::skHalfPi),
|
|
||||||
sin(mYaw - Math::skHalfPi),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
mUpVector = mRightVector.Cross(mDirection);
|
|
||||||
|
|
||||||
// Update position
|
|
||||||
if (mMode == eOrbitCamera)
|
|
||||||
{
|
|
||||||
if (mOrbitDistance < 1.f) mOrbitDistance = 1.f;
|
|
||||||
mPosition = mOrbitTarget + (mDirection * -mOrbitDistance);
|
|
||||||
}
|
|
||||||
|
|
||||||
mViewOutdated = true;
|
|
||||||
mFrustumPlanesOutdated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::UpdateView()
|
void CCamera::UpdateTransform() const
|
||||||
|
{
|
||||||
|
// Transform should be marked dirty when pitch, yaw, or orbit target/distance are changed
|
||||||
|
if (mTransformDirty)
|
||||||
|
{
|
||||||
|
mDirection = CVector3f(
|
||||||
|
cos(mPitch) * cos(mYaw),
|
||||||
|
cos(mPitch) * sin(mYaw),
|
||||||
|
sin(mPitch)
|
||||||
|
);
|
||||||
|
|
||||||
|
mRightVector = CVector3f(
|
||||||
|
cos(mYaw - Math::skHalfPi),
|
||||||
|
sin(mYaw - Math::skHalfPi),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
mUpVector = mRightVector.Cross(mDirection);
|
||||||
|
|
||||||
|
// Update position
|
||||||
|
if (mMode == eOrbitCamera)
|
||||||
|
{
|
||||||
|
if (mOrbitDistance < 1.f) mOrbitDistance = 1.f;
|
||||||
|
mPosition = mOrbitTarget + (mDirection * -mOrbitDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
mViewDirty = true;
|
||||||
|
mFrustumPlanesDirty = true;
|
||||||
|
mTransformDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCamera::UpdateView() const
|
||||||
{
|
{
|
||||||
// todo: don't use glm
|
// todo: don't use glm
|
||||||
Update();
|
UpdateTransform();
|
||||||
|
|
||||||
glm::vec3 glmpos(mPosition.x, mPosition.y, mPosition.z);
|
if (mViewDirty)
|
||||||
glm::vec3 glmdir(mDirection.x, mDirection.y, mDirection.z);
|
{
|
||||||
glm::vec3 glmup(mUpVector.x, mUpVector.y, mUpVector.z);
|
glm::vec3 glmpos(mPosition.x, mPosition.y, mPosition.z);
|
||||||
mCachedViewMatrix = CMatrix4f::FromGlmMat4(glm::lookAt(glmpos, glmpos + glmdir, glmup)).Transpose();
|
glm::vec3 glmdir(mDirection.x, mDirection.y, mDirection.z);
|
||||||
mViewOutdated = false;
|
glm::vec3 glmup(mUpVector.x, mUpVector.y, mUpVector.z);
|
||||||
|
mViewMatrix = CMatrix4f::FromGlmMat4(glm::lookAt(glmpos, glmpos + glmdir, glmup)).Transpose();
|
||||||
|
mViewDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::UpdateProjection()
|
void CCamera::UpdateProjection() const
|
||||||
{
|
{
|
||||||
mCachedProjectionMatrix = Math::PerspectiveMatrix(55.f, mAspectRatio, 0.1f, 4096.f);
|
if (mProjectionDirty)
|
||||||
mProjectionOutdated = false;
|
{
|
||||||
|
mProjectionMatrix = Math::PerspectiveMatrix(55.f, mAspectRatio, 0.1f, 4096.f);
|
||||||
|
mProjectionDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::UpdateFrustum()
|
void CCamera::UpdateFrustum() const
|
||||||
{
|
{
|
||||||
mCachedFrustumPlanes.SetPlanes(mPosition, mDirection, 55.f, mAspectRatio, 0.1f, 4096.f);
|
UpdateTransform();
|
||||||
mFrustumPlanesOutdated = false;
|
|
||||||
|
if (mFrustumPlanesDirty)
|
||||||
|
{
|
||||||
|
mFrustumPlanes.SetPlanes(mPosition, mDirection, 55.f, mAspectRatio, 0.1f, 4096.f);
|
||||||
|
mFrustumPlanesDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,28 +16,38 @@ enum ECameraMoveMode
|
||||||
eFreeCamera, eOrbitCamera
|
eFreeCamera, eOrbitCamera
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This class uses a lot of mutable members as an optimization so that they can
|
||||||
|
* be updated as infrequently as possible (eg only when the values are requested
|
||||||
|
* the next time after changes are made) while still always returning the correct
|
||||||
|
* value via the const get functions. They are not modified in const functions
|
||||||
|
* beyond ensuring that all data is valid and synced with everything else (eg
|
||||||
|
* mPosition is only modified to ensure it's correct in orbit mode given the
|
||||||
|
* target/distance/pitch/yaw; it won't be modified as a camera snap in a const
|
||||||
|
* function). */
|
||||||
class CCamera
|
class CCamera
|
||||||
{
|
{
|
||||||
ECameraMoveMode mMode;
|
ECameraMoveMode mMode;
|
||||||
CVector3f mPosition;
|
mutable CVector3f mPosition;
|
||||||
CVector3f mDirection;
|
mutable CVector3f mDirection;
|
||||||
CVector3f mRightVector;
|
mutable CVector3f mRightVector;
|
||||||
CVector3f mUpVector;
|
mutable CVector3f mUpVector;
|
||||||
float mAspectRatio;
|
float mAspectRatio;
|
||||||
|
|
||||||
float mYaw;
|
float mYaw;
|
||||||
float mPitch;
|
float mPitch;
|
||||||
CVector3f mOrbitTarget;
|
CVector3f mOrbitTarget;
|
||||||
float mOrbitDistance;
|
mutable float mOrbitDistance;
|
||||||
float mMoveSpeed;
|
float mMoveSpeed;
|
||||||
float mLookSpeed;
|
float mLookSpeed;
|
||||||
|
|
||||||
CMatrix4f mCachedViewMatrix;
|
mutable CMatrix4f mViewMatrix;
|
||||||
CMatrix4f mCachedProjectionMatrix;
|
mutable CMatrix4f mProjectionMatrix;
|
||||||
CFrustumPlanes mCachedFrustumPlanes;
|
mutable CFrustumPlanes mFrustumPlanes;
|
||||||
bool mViewOutdated;
|
|
||||||
bool mProjectionOutdated;
|
mutable bool mTransformDirty;
|
||||||
bool mFrustumPlanesOutdated;
|
mutable bool mViewDirty;
|
||||||
|
mutable bool mProjectionDirty;
|
||||||
|
mutable bool mFrustumPlanesDirty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCamera();
|
CCamera();
|
||||||
|
@ -49,12 +59,12 @@ public:
|
||||||
void Snap(CVector3f Position);
|
void Snap(CVector3f Position);
|
||||||
void ProcessKeyInput(EKeyInputs KeyFlags, double DeltaTime);
|
void ProcessKeyInput(EKeyInputs KeyFlags, double DeltaTime);
|
||||||
void ProcessMouseInput(EKeyInputs KeyFlags, EMouseInputs MouseFlags, float XMovement, float YMovement);
|
void ProcessMouseInput(EKeyInputs KeyFlags, EMouseInputs MouseFlags, float XMovement, float YMovement);
|
||||||
CRay CastRay(CVector2f DeviceCoords);
|
CRay CastRay(CVector2f DeviceCoords) const;
|
||||||
void LoadMatrices();
|
void LoadMatrices() const;
|
||||||
|
|
||||||
void SetMoveMode(ECameraMoveMode Mode);
|
void SetMoveMode(ECameraMoveMode Mode);
|
||||||
void SetOrbit(const CVector3f& OrbitTarget, float Distance);
|
void SetOrbit(const CVector3f& OrbitTarget, float Distance);
|
||||||
void SetOrbit(const CAABox& OrbitTarget, float DistScale = 2.5f);
|
void SetOrbit(const CAABox& OrbitTarget, float DistScale = 4.f);
|
||||||
void SetOrbitDistance(float Distance);
|
void SetOrbitDistance(float Distance);
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
|
@ -66,13 +76,11 @@ public:
|
||||||
float Pitch() const;
|
float Pitch() const;
|
||||||
float FieldOfView() const;
|
float FieldOfView() const;
|
||||||
ECameraMoveMode MoveMode() const;
|
ECameraMoveMode MoveMode() const;
|
||||||
const CMatrix4f& ViewMatrix();
|
const CMatrix4f& ViewMatrix() const;
|
||||||
const CMatrix4f& ProjectionMatrix();
|
const CMatrix4f& ProjectionMatrix() const;
|
||||||
const CFrustumPlanes& FrustumPlanes();
|
const CFrustumPlanes& FrustumPlanes() const;
|
||||||
|
|
||||||
// Setters
|
// Setters
|
||||||
void SetPosition(CVector3f Position);
|
|
||||||
void SetDirection(CVector3f Direction);
|
|
||||||
void SetYaw(float Yaw);
|
void SetYaw(float Yaw);
|
||||||
void SetPitch(float Pitch);
|
void SetPitch(float Pitch);
|
||||||
void SetMoveSpeed(float MoveSpeed);
|
void SetMoveSpeed(float MoveSpeed);
|
||||||
|
@ -81,10 +89,11 @@ public:
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
private:
|
private:
|
||||||
void Update();
|
void ValidatePitch();
|
||||||
void UpdateView();
|
void UpdateTransform() const;
|
||||||
void UpdateProjection();
|
void UpdateView() const;
|
||||||
void UpdateFrustum();
|
void UpdateProjection() const;
|
||||||
|
void UpdateFrustum() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CCAMERA_H
|
#endif // CCAMERA_H
|
||||||
|
|
|
@ -12,15 +12,15 @@ CLight::CLight()
|
||||||
mDirection = skDefaultLightDir;
|
mDirection = skDefaultLightDir;
|
||||||
mDistAttenCoefficients = CVector3f(0.f, 1.f, 0.f);
|
mDistAttenCoefficients = CVector3f(0.f, 1.f, 0.f);
|
||||||
mAngleAttenCoefficients = CVector3f(0.f, 1.f, 0.f);
|
mAngleAttenCoefficients = CVector3f(0.f, 1.f, 0.f);
|
||||||
mRadius = 0.f;
|
mCachedRadius = 0.f;
|
||||||
mIntensity = 0.f;
|
mCachedIntensity = 0.f;
|
||||||
mFlags = CLIGHT_NO_RADIUS | CLIGHT_NO_INTENSITY;
|
mDirtyFlags = CLIGHT_NO_RADIUS | CLIGHT_NO_INTENSITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ DATA MANIPULATION ************
|
// ************ DATA MANIPULATION ************
|
||||||
|
|
||||||
// This function is reverse engineered from the kiosk demo's code
|
// This function is reverse engineered from the kiosk demo's code
|
||||||
float CLight::CalculateRadius()
|
float CLight::CalculateRadius() const
|
||||||
{
|
{
|
||||||
if ((mDistAttenCoefficients.y >= FLT_EPSILON) ||
|
if ((mDistAttenCoefficients.y >= FLT_EPSILON) ||
|
||||||
(mDistAttenCoefficients.z >= FLT_EPSILON))
|
(mDistAttenCoefficients.z >= FLT_EPSILON))
|
||||||
|
@ -53,7 +53,7 @@ float CLight::CalculateRadius()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is also reverse engineered from the kiosk demo's code
|
// This function is also reverse engineered from the kiosk demo's code
|
||||||
float CLight::CalculateIntensity()
|
float CLight::CalculateIntensity() const
|
||||||
{
|
{
|
||||||
float Multiplier = (mType == eCustom) ? mAngleAttenCoefficients.x : 1.0f;
|
float Multiplier = (mType == eCustom) ? mAngleAttenCoefficients.x : 1.0f;
|
||||||
float ColorR = float(mColor.r) / 255.f;
|
float ColorR = float(mColor.r) / 255.f;
|
||||||
|
@ -118,26 +118,26 @@ CVector3f CLight::GetAngleAttenuation() const
|
||||||
return mAngleAttenCoefficients;
|
return mAngleAttenCoefficients;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CLight::GetRadius()
|
float CLight::GetRadius() const
|
||||||
{
|
{
|
||||||
if (mFlags & CLIGHT_NO_RADIUS)
|
if (mDirtyFlags & CLIGHT_NO_RADIUS)
|
||||||
{
|
{
|
||||||
mRadius = CalculateRadius();
|
mCachedRadius = CalculateRadius();
|
||||||
mFlags &= ~CLIGHT_NO_RADIUS;
|
mDirtyFlags &= ~CLIGHT_NO_RADIUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mRadius * 2;
|
return mCachedRadius * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CLight::GetIntensity()
|
float CLight::GetIntensity() const
|
||||||
{
|
{
|
||||||
if (mFlags & CLIGHT_NO_INTENSITY)
|
if (mDirtyFlags & CLIGHT_NO_INTENSITY)
|
||||||
{
|
{
|
||||||
mIntensity = CalculateIntensity();
|
mCachedIntensity = CalculateIntensity();
|
||||||
mFlags &= ~CLIGHT_NO_INTENSITY;
|
mDirtyFlags &= ~CLIGHT_NO_INTENSITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mIntensity;
|
return mCachedIntensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ SETTERS ************
|
// ************ SETTERS ************
|
||||||
|
@ -159,7 +159,7 @@ void CLight::SetDirection(const CVector3f& Direction)
|
||||||
void CLight::SetColor(const CColor& Color)
|
void CLight::SetColor(const CColor& Color)
|
||||||
{
|
{
|
||||||
mColor = Color;
|
mColor = Color;
|
||||||
mFlags = CLIGHT_NO_RADIUS | CLIGHT_NO_INTENSITY;
|
mDirtyFlags = CLIGHT_NO_RADIUS | CLIGHT_NO_INTENSITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLight::SetSpotCutoff(float Cutoff)
|
void CLight::SetSpotCutoff(float Cutoff)
|
||||||
|
|
|
@ -6,12 +6,9 @@
|
||||||
#include <Common/CVector3f.h>
|
#include <Common/CVector3f.h>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
/**
|
/* CLight is currently heavily based on the lights system from Metroid Prime,
|
||||||
* CLight is currently heavily based on the lights system from Metroid Prime,
|
|
||||||
* including code reverse engineered from the game's executable. Not yet sure
|
* including code reverse engineered from the game's executable. Not yet sure
|
||||||
* how much needs to be modified to properly support Prime 3 and DKCR; they
|
* how much needs to be modified to properly support DKCR. */
|
||||||
* have a new light structure.
|
|
||||||
*/
|
|
||||||
enum ELightType
|
enum ELightType
|
||||||
{
|
{
|
||||||
eLocalAmbient = 0,
|
eLocalAmbient = 0,
|
||||||
|
@ -31,17 +28,17 @@ class CLight
|
||||||
CVector3f mDistAttenCoefficients;
|
CVector3f mDistAttenCoefficients;
|
||||||
CVector3f mAngleAttenCoefficients;
|
CVector3f mAngleAttenCoefficients;
|
||||||
|
|
||||||
float mRadius;
|
mutable float mCachedRadius;
|
||||||
float mIntensity;
|
mutable float mCachedIntensity;
|
||||||
u8 mFlags;
|
mutable u8 mDirtyFlags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CLight();
|
CLight();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Data Manipulation
|
// Data Manipulation
|
||||||
float CalculateRadius();
|
float CalculateRadius() const;
|
||||||
float CalculateIntensity();
|
float CalculateIntensity() const;
|
||||||
CVector3f CalculateSpotAngleAtten();
|
CVector3f CalculateSpotAngleAtten();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -53,8 +50,8 @@ public:
|
||||||
CColor GetColor() const;
|
CColor GetColor() const;
|
||||||
CVector3f GetDistAttenuation() const;
|
CVector3f GetDistAttenuation() const;
|
||||||
CVector3f GetAngleAttenuation() const;
|
CVector3f GetAngleAttenuation() const;
|
||||||
float GetRadius();
|
float GetRadius() const;
|
||||||
float GetIntensity();
|
float GetIntensity() const;
|
||||||
|
|
||||||
// Setters
|
// Setters
|
||||||
void SetLayer(u32 index);
|
void SetLayer(u32 index);
|
||||||
|
|
|
@ -134,3 +134,9 @@ CVector2f CLightNode::BillboardScale()
|
||||||
{
|
{
|
||||||
return AbsoluteScale().xz() * 0.75f;
|
return AbsoluteScale().xz() * 0.75f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CLightNode::CalculateTransform(CTransform4f& rOut) const
|
||||||
|
{
|
||||||
|
// Billboards don't rotate and their scale is applied separately
|
||||||
|
rOut.Translate(AbsolutePosition());
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ public:
|
||||||
SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, const SViewInfo& ViewInfo);
|
SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, const SViewInfo& ViewInfo);
|
||||||
CLight* Light();
|
CLight* Light();
|
||||||
CVector2f BillboardScale();
|
CVector2f BillboardScale();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void CalculateTransform(CTransform4f& rOut) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLIGHTNODE_H
|
#endif // CLIGHTNODE_H
|
||||||
|
|
|
@ -113,6 +113,8 @@ void CModelNode::SetModel(CModel *pModel)
|
||||||
SetName(pModel->Source());
|
SetName(pModel->Source());
|
||||||
mLocalAABox = mpModel->AABox();
|
mLocalAABox = mpModel->AABox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MarkTransformChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelNode::ForceAlphaEnabled(bool Enable)
|
void CModelNode::ForceAlphaEnabled(bool Enable)
|
||||||
|
|
|
@ -21,8 +21,7 @@ CSceneNode::CSceneNode(CSceneManager *pScene, CSceneNode *pParent)
|
||||||
mPosition = CVector3f::skZero;
|
mPosition = CVector3f::skZero;
|
||||||
mRotation = CQuaternion::skIdentity;
|
mRotation = CQuaternion::skIdentity;
|
||||||
mScale = CVector3f::skOne;
|
mScale = CVector3f::skOne;
|
||||||
mScaleMultiplier = CVector3f::skOne;
|
_mTransformDirty = true;
|
||||||
_mTransformOutdated = true;
|
|
||||||
|
|
||||||
_mInheritsPosition = true;
|
_mInheritsPosition = true;
|
||||||
_mInheritsRotation = true;
|
_mInheritsRotation = true;
|
||||||
|
@ -208,7 +207,7 @@ void CSceneNode::LoadLights(const SViewInfo& ViewInfo)
|
||||||
CGraphics::UpdateLightBlock();
|
CGraphics::UpdateLightBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSceneNode::DrawBoundingBox()
|
void CSceneNode::DrawBoundingBox() const
|
||||||
{
|
{
|
||||||
CDrawUtil::DrawWireCube(AABox(), CColor::skWhite);
|
CDrawUtil::DrawWireCube(AABox(), CColor::skWhite);
|
||||||
}
|
}
|
||||||
|
@ -267,52 +266,49 @@ void CSceneNode::Scale(const CVector3f& scale)
|
||||||
MarkTransformChanged();
|
MarkTransformChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSceneNode::UpdateTransform()
|
void CSceneNode::ForceRecalculateTransform() const
|
||||||
{
|
|
||||||
if (_mTransformOutdated)
|
|
||||||
{
|
|
||||||
ForceRecalculateTransform();
|
|
||||||
_mTransformOutdated = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSceneNode::ForceRecalculateTransform()
|
|
||||||
{
|
{
|
||||||
_mCachedTransform = CTransform4f::skIdentity;
|
_mCachedTransform = CTransform4f::skIdentity;
|
||||||
_mCachedTransform.Scale(AbsoluteScale());
|
CalculateTransform(_mCachedTransform);
|
||||||
_mCachedTransform.Rotate(AbsoluteRotation());
|
|
||||||
_mCachedTransform.Translate(AbsolutePosition());
|
|
||||||
_mCachedAABox = mLocalAABox.Transformed(_mCachedTransform);
|
_mCachedAABox = mLocalAABox.Transformed(_mCachedTransform);
|
||||||
|
|
||||||
// Sync with children - only needed if caller hasn't marked transform changed already
|
// Sync with children - only needed if caller hasn't marked transform changed already
|
||||||
// If so, the children will already be marked
|
// If so, the children will already be marked
|
||||||
if (!_mTransformOutdated)
|
if (!_mTransformDirty)
|
||||||
{
|
{
|
||||||
for (auto it = mChildren.begin(); it != mChildren.end(); it++)
|
for (auto it = mChildren.begin(); it != mChildren.end(); it++)
|
||||||
(*it)->MarkTransformChanged();
|
(*it)->MarkTransformChanged();
|
||||||
}
|
}
|
||||||
_mTransformOutdated = false;
|
_mTransformDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSceneNode::MarkTransformChanged()
|
void CSceneNode::MarkTransformChanged() const
|
||||||
{
|
{
|
||||||
if (!_mTransformOutdated)
|
if (!_mTransformDirty)
|
||||||
{
|
{
|
||||||
for (auto it = mChildren.begin(); it != mChildren.end(); it++)
|
for (auto it = mChildren.begin(); it != mChildren.end(); it++)
|
||||||
(*it)->MarkTransformChanged();
|
(*it)->MarkTransformChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
_mTransformOutdated = true;
|
_mTransformDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CTransform4f& CSceneNode::Transform()
|
const CTransform4f& CSceneNode::Transform() const
|
||||||
{
|
{
|
||||||
if (_mTransformOutdated)
|
if (_mTransformDirty)
|
||||||
ForceRecalculateTransform();
|
ForceRecalculateTransform();
|
||||||
|
|
||||||
return _mCachedTransform;
|
return _mCachedTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSceneNode::CalculateTransform(CTransform4f& rOut) const
|
||||||
|
{
|
||||||
|
// Default implementation for virtual function
|
||||||
|
rOut.Scale(AbsoluteScale());
|
||||||
|
rOut.Rotate(AbsoluteRotation());
|
||||||
|
rOut.Translate(AbsolutePosition());
|
||||||
|
}
|
||||||
|
|
||||||
// ************ GETTERS ************
|
// ************ GETTERS ************
|
||||||
TString CSceneNode::Name() const
|
TString CSceneNode::Name() const
|
||||||
{
|
{
|
||||||
|
@ -324,7 +320,7 @@ CSceneNode* CSceneNode::Parent() const
|
||||||
return mpParent;
|
return mpParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSceneManager* CSceneNode::Scene()
|
CSceneManager* CSceneNode::Scene() const
|
||||||
{
|
{
|
||||||
return mpScene;
|
return mpScene;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +362,7 @@ CVector3f CSceneNode::LocalScale() const
|
||||||
|
|
||||||
CVector3f CSceneNode::AbsoluteScale() const
|
CVector3f CSceneNode::AbsoluteScale() const
|
||||||
{
|
{
|
||||||
CVector3f ret = mScale * mScaleMultiplier;
|
CVector3f ret = mScale;
|
||||||
|
|
||||||
if ((mpParent) && (InheritsScale()))
|
if ((mpParent) && (InheritsScale()))
|
||||||
ret *= mpParent->AbsoluteScale();
|
ret *= mpParent->AbsoluteScale();
|
||||||
|
@ -374,15 +370,15 @@ CVector3f CSceneNode::AbsoluteScale() const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAABox CSceneNode::AABox()
|
CAABox CSceneNode::AABox() const
|
||||||
{
|
{
|
||||||
if (_mTransformOutdated)
|
if (_mTransformDirty)
|
||||||
ForceRecalculateTransform();
|
ForceRecalculateTransform();
|
||||||
|
|
||||||
return _mCachedAABox;
|
return _mCachedAABox;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f CSceneNode::CenterPoint()
|
CVector3f CSceneNode::CenterPoint() const
|
||||||
{
|
{
|
||||||
return AABox().Center();
|
return AABox().Center();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,9 @@ class CSceneManager;
|
||||||
class CSceneNode : public IRenderable
|
class CSceneNode : public IRenderable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
CTransform4f _mCachedTransform;
|
mutable CTransform4f _mCachedTransform;
|
||||||
CAABox _mCachedAABox;
|
mutable CAABox _mCachedAABox;
|
||||||
bool _mTransformOutdated;
|
mutable bool _mTransformDirty;
|
||||||
|
|
||||||
bool _mInheritsPosition;
|
bool _mInheritsPosition;
|
||||||
bool _mInheritsRotation;
|
bool _mInheritsRotation;
|
||||||
|
@ -38,7 +38,6 @@ protected:
|
||||||
CVector3f mPosition;
|
CVector3f mPosition;
|
||||||
CQuaternion mRotation;
|
CQuaternion mRotation;
|
||||||
CVector3f mScale;
|
CVector3f mScale;
|
||||||
CVector3f mScaleMultiplier;
|
|
||||||
CAABox mLocalAABox;
|
CAABox mLocalAABox;
|
||||||
|
|
||||||
bool mMouseHovering;
|
bool mMouseHovering;
|
||||||
|
@ -70,30 +69,32 @@ public:
|
||||||
void LoadModelMatrix();
|
void LoadModelMatrix();
|
||||||
void BuildLightList(CGameArea *pArea);
|
void BuildLightList(CGameArea *pArea);
|
||||||
void LoadLights(const SViewInfo& ViewInfo);
|
void LoadLights(const SViewInfo& ViewInfo);
|
||||||
void DrawBoundingBox();
|
void DrawBoundingBox() const;
|
||||||
void AddSurfacesToRenderer(CRenderer *pRenderer, CModel *pModel, u32 MatSet, const SViewInfo& ViewInfo);
|
void AddSurfacesToRenderer(CRenderer *pRenderer, CModel *pModel, u32 MatSet, const SViewInfo& ViewInfo);
|
||||||
|
|
||||||
// Transform
|
// Transform
|
||||||
void Translate(const CVector3f& translation, ETransformSpace transformSpace);
|
void Translate(const CVector3f& translation, ETransformSpace transformSpace);
|
||||||
void Rotate(const CQuaternion& rotation, ETransformSpace transformSpace);
|
void Rotate(const CQuaternion& rotation, ETransformSpace transformSpace);
|
||||||
void Scale(const CVector3f& scale);
|
void Scale(const CVector3f& scale);
|
||||||
void UpdateTransform();
|
const CTransform4f& Transform() const;
|
||||||
void ForceRecalculateTransform();
|
protected:
|
||||||
void MarkTransformChanged();
|
void MarkTransformChanged() const;
|
||||||
const CTransform4f& Transform();
|
void ForceRecalculateTransform() const;
|
||||||
|
virtual void CalculateTransform(CTransform4f& rOut) const;
|
||||||
|
|
||||||
|
public:
|
||||||
// Getters
|
// Getters
|
||||||
TString Name() const;
|
TString Name() const;
|
||||||
CSceneNode* Parent() const;
|
CSceneNode* Parent() const;
|
||||||
CSceneManager* Scene();
|
CSceneManager* Scene() const;
|
||||||
CVector3f LocalPosition() const;
|
CVector3f LocalPosition() const;
|
||||||
CVector3f AbsolutePosition() const;
|
CVector3f AbsolutePosition() const;
|
||||||
CQuaternion LocalRotation() const;
|
CQuaternion LocalRotation() const;
|
||||||
CQuaternion AbsoluteRotation() const;
|
CQuaternion AbsoluteRotation() const;
|
||||||
CVector3f LocalScale() const;
|
CVector3f LocalScale() const;
|
||||||
CVector3f AbsoluteScale() const;
|
CVector3f AbsoluteScale() const;
|
||||||
CAABox AABox();
|
CAABox AABox() const;
|
||||||
CVector3f CenterPoint();
|
CVector3f CenterPoint() const;
|
||||||
u32 LightLayerIndex() const;
|
u32 LightLayerIndex() const;
|
||||||
bool MarkedVisible() const;
|
bool MarkedVisible() const;
|
||||||
bool IsMouseHovering() const;
|
bool IsMouseHovering() const;
|
||||||
|
|
|
@ -29,16 +29,12 @@ CScriptNode::CScriptNode(CSceneManager *pScene, CSceneNode *pParent, CScriptObje
|
||||||
// Determine transform
|
// Determine transform
|
||||||
mPosition = mpInstance->Position();
|
mPosition = mpInstance->Position();
|
||||||
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
|
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
|
||||||
SetName("[" + pTemp->TemplateName(mpInstance->NumProperties()) + "] " + mpInstance->InstanceName());
|
mScale = mpInstance->Scale();
|
||||||
|
mScaleMultiplier = mpInstance->Template()->PreviewScale();
|
||||||
if (pTemp->ScaleType() == CScriptTemplate::eScaleEnabled)
|
|
||||||
{
|
|
||||||
mScale = mpInstance->Scale();
|
|
||||||
mScaleMultiplier = mpInstance->Template()->PreviewScale();
|
|
||||||
}
|
|
||||||
|
|
||||||
MarkTransformChanged();
|
MarkTransformChanged();
|
||||||
|
|
||||||
|
SetName("[" + pTemp->TemplateName(mpInstance->NumProperties()) + "] " + mpInstance->InstanceName());
|
||||||
|
|
||||||
// Determine display assets
|
// Determine display assets
|
||||||
mpActiveModel = mpInstance->GetDisplayModel();
|
mpActiveModel = mpInstance->GetDisplayModel();
|
||||||
mModelToken = CToken(mpActiveModel);
|
mModelToken = CToken(mpActiveModel);
|
||||||
|
@ -72,8 +68,7 @@ CScriptNode::CScriptNode(CSceneManager *pScene, CSceneNode *pParent, CScriptObje
|
||||||
if (pVolumeModel)
|
if (pVolumeModel)
|
||||||
{
|
{
|
||||||
mpVolumePreviewNode = new CModelNode(pScene, this, pVolumeModel);
|
mpVolumePreviewNode = new CModelNode(pScene, this, pVolumeModel);
|
||||||
mpVolumePreviewNode->SetInheritance(true, (shape != eAxisAlignedBoxShape), false);
|
mpVolumePreviewNode->SetInheritance(true, (shape != eAxisAlignedBoxShape), true);
|
||||||
mpVolumePreviewNode->Scale(mpInstance->Scale());
|
|
||||||
mpVolumePreviewNode->ForceAlphaEnabled(true);
|
mpVolumePreviewNode->ForceAlphaEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,7 +157,7 @@ void CScriptNode::Draw(ERenderOptions Options, int ComponentIndex, const SViewIn
|
||||||
if (!mpInstance) return;
|
if (!mpInstance) return;
|
||||||
|
|
||||||
// Draw model
|
// Draw model
|
||||||
if (mpActiveModel || !mpBillboard)
|
if (UsesModel())
|
||||||
{
|
{
|
||||||
CGraphics::SetupAmbientColor();
|
CGraphics::SetupAmbientColor();
|
||||||
CGraphics::UpdateVertexBlock();
|
CGraphics::UpdateVertexBlock();
|
||||||
|
@ -204,7 +199,7 @@ void CScriptNode::DrawSelection()
|
||||||
glBlendFunc(GL_ONE, GL_ZERO);
|
glBlendFunc(GL_ONE, GL_ZERO);
|
||||||
|
|
||||||
// Draw wireframe for models; billboards only get tinted
|
// Draw wireframe for models; billboards only get tinted
|
||||||
if (mpActiveModel || !mpBillboard)
|
if (UsesModel())
|
||||||
{
|
{
|
||||||
LoadModelMatrix();
|
LoadModelMatrix();
|
||||||
CModel *pModel = (mpActiveModel ? mpActiveModel : CDrawUtil::GetCubeModel());
|
CModel *pModel = (mpActiveModel ? mpActiveModel : CDrawUtil::GetCubeModel());
|
||||||
|
@ -258,7 +253,7 @@ void CScriptNode::RayAABoxIntersectTest(CRayCollisionTester& Tester, const SView
|
||||||
// Otherwise, proceed with the ray test as normal...
|
// Otherwise, proceed with the ray test as normal...
|
||||||
const CRay& Ray = Tester.Ray();
|
const CRay& Ray = Tester.Ray();
|
||||||
|
|
||||||
if (mpActiveModel || !mpBillboard)
|
if (UsesModel())
|
||||||
{
|
{
|
||||||
std::pair<bool,float> BoxResult = AABox().IntersectsRay(Ray);
|
std::pair<bool,float> BoxResult = AABox().IntersectsRay(Ray);
|
||||||
|
|
||||||
|
@ -294,7 +289,7 @@ SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& Ray, u32 AssetID,
|
||||||
if (options & eDrawObjects || ViewInfo.GameMode)
|
if (options & eDrawObjects || ViewInfo.GameMode)
|
||||||
{
|
{
|
||||||
// Model test
|
// Model test
|
||||||
if (mpActiveModel || !mpBillboard)
|
if (UsesModel())
|
||||||
{
|
{
|
||||||
CModel *pModel = (mpActiveModel ? mpActiveModel : CDrawUtil::GetCubeModel());
|
CModel *pModel = (mpActiveModel ? mpActiveModel : CDrawUtil::GetCubeModel());
|
||||||
|
|
||||||
|
@ -381,21 +376,6 @@ CColor CScriptNode::TintColor(const SViewInfo &ViewInfo) const
|
||||||
return BaseColor;
|
return BaseColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor CScriptNode::WireframeColor() const
|
|
||||||
{
|
|
||||||
return CColor((u8) 12, 135, 194, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
CScriptObject* CScriptNode::Object()
|
|
||||||
{
|
|
||||||
return mpInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
CModel* CScriptNode::ActiveModel()
|
|
||||||
{
|
|
||||||
return mpActiveModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScriptNode::GeneratePosition()
|
void CScriptNode::GeneratePosition()
|
||||||
{
|
{
|
||||||
if (!mHasValidPosition)
|
if (!mHasValidPosition)
|
||||||
|
@ -457,12 +437,32 @@ void CScriptNode::GeneratePosition()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CScriptNode::HasPreviewVolume()
|
CColor CScriptNode::WireframeColor() const
|
||||||
|
{
|
||||||
|
return CColor((u8) 12, 135, 194, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
CScriptObject* CScriptNode::Object() const
|
||||||
|
{
|
||||||
|
return mpInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
CModel* CScriptNode::ActiveModel() const
|
||||||
|
{
|
||||||
|
return mpActiveModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CScriptNode::UsesModel() const
|
||||||
|
{
|
||||||
|
return ((mpActiveModel != nullptr) || (mpBillboard == nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CScriptNode::HasPreviewVolume() const
|
||||||
{
|
{
|
||||||
return mHasVolumePreview;
|
return mHasVolumePreview;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAABox CScriptNode::PreviewVolumeAABox()
|
CAABox CScriptNode::PreviewVolumeAABox() const
|
||||||
{
|
{
|
||||||
if (!mHasVolumePreview)
|
if (!mHasVolumePreview)
|
||||||
return CAABox::skZero;
|
return CAABox::skZero;
|
||||||
|
@ -470,8 +470,25 @@ CAABox CScriptNode::PreviewVolumeAABox()
|
||||||
return mpVolumePreviewNode->AABox();
|
return mpVolumePreviewNode->AABox();
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector2f CScriptNode::BillboardScale()
|
CVector2f CScriptNode::BillboardScale() const
|
||||||
{
|
{
|
||||||
CVector2f out = (mpInstance->Template()->ScaleType() == CScriptTemplate::eScaleEnabled ? AbsoluteScale().xz() : CVector2f(1.f));
|
CVector2f out = (mpInstance->Template()->ScaleType() == CScriptTemplate::eScaleEnabled ? AbsoluteScale().xz() : CVector2f(1.f));
|
||||||
return out * 0.5f;
|
return out * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ************ PROTECTED ************
|
||||||
|
void CScriptNode::CalculateTransform(CTransform4f& rOut) const
|
||||||
|
{
|
||||||
|
CScriptTemplate *pTemp = mpInstance->Template();
|
||||||
|
|
||||||
|
if (pTemp->ScaleType() != CScriptTemplate::eScaleDisabled)
|
||||||
|
{
|
||||||
|
CVector3f Scale = (HasPreviewVolume() ? CVector3f::skOne : AbsoluteScale());
|
||||||
|
rOut.Scale(Scale * mScaleMultiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UsesModel() && pTemp->RotationType() == CScriptTemplate::eRotationEnabled)
|
||||||
|
rOut.Rotate(AbsoluteRotation());
|
||||||
|
|
||||||
|
rOut.Translate(AbsolutePosition());
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ class CScriptNode : public CSceneNode
|
||||||
|
|
||||||
bool mHasValidPosition;
|
bool mHasValidPosition;
|
||||||
bool mHasVolumePreview;
|
bool mHasVolumePreview;
|
||||||
|
float mScaleMultiplier;
|
||||||
CModelNode *mpVolumePreviewNode;
|
CModelNode *mpVolumePreviewNode;
|
||||||
|
|
||||||
CLightParameters *mpLightParameters;
|
CLightParameters *mpLightParameters;
|
||||||
|
@ -36,12 +37,16 @@ public:
|
||||||
CColor TintColor(const SViewInfo &ViewInfo) const;
|
CColor TintColor(const SViewInfo &ViewInfo) const;
|
||||||
CColor WireframeColor() const;
|
CColor WireframeColor() const;
|
||||||
|
|
||||||
CScriptObject* Object();
|
|
||||||
CModel* ActiveModel();
|
|
||||||
void GeneratePosition();
|
void GeneratePosition();
|
||||||
bool HasPreviewVolume();
|
CScriptObject* Object() const;
|
||||||
CAABox PreviewVolumeAABox();
|
CModel* ActiveModel() const;
|
||||||
CVector2f BillboardScale();
|
bool UsesModel() const;
|
||||||
|
bool HasPreviewVolume() const;
|
||||||
|
CAABox PreviewVolumeAABox() const;
|
||||||
|
CVector2f BillboardScale() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void CalculateTransform(CTransform4f& rOut) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSCRIPTNODE_H
|
#endif // CSCRIPTNODE_H
|
||||||
|
|
|
@ -64,7 +64,7 @@ void CDamageableTriggerExtra::CreateMaterial()
|
||||||
mpMat->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
mpMat->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
mpMat->SetLightingEnabled(true);
|
mpMat->SetLightingEnabled(true);
|
||||||
mpMat->SetOptions(CMaterial::eTransparent);
|
mpMat->SetOptions(CMaterial::eTransparent);
|
||||||
mpMat->SetKonst(CColor((float) 1.f, 1.f, 1.f, 51.f / 255), 0);
|
mpMat->SetKonst(CColor((float) 1.f, 1.f, 1.f, 0.2f), 0);
|
||||||
mpMat->SetNumPasses(3);
|
mpMat->SetNumPasses(3);
|
||||||
|
|
||||||
CMaterialPass *pPassA = mpMat->Pass(0);
|
CMaterialPass *pPassA = mpMat->Pass(0);
|
||||||
|
|
|
@ -153,7 +153,6 @@ void CModelEditorWindow::RefreshViewport()
|
||||||
void CModelEditorWindow::SetActiveModel(CModel *pModel)
|
void CModelEditorWindow::SetActiveModel(CModel *pModel)
|
||||||
{
|
{
|
||||||
mpCurrentModelNode->SetModel(pModel);
|
mpCurrentModelNode->SetModel(pModel);
|
||||||
mpCurrentModelNode->MarkTransformChanged();
|
|
||||||
mpCurrentModel = pModel;
|
mpCurrentModel = pModel;
|
||||||
mModelToken = CToken(pModel);
|
mModelToken = CToken(pModel);
|
||||||
ui->Viewport->Camera().SetOrbit(pModel->AABox());
|
ui->Viewport->Camera().SetOrbit(pModel->AABox());
|
||||||
|
|
|
@ -180,7 +180,7 @@ void CWorldEditor::UpdateGizmoUI()
|
||||||
if (mGizmoTransforming && mGizmo.HasTransformed())
|
if (mGizmoTransforming && mGizmo.HasTransformed())
|
||||||
spinBoxValue = mGizmo.TotalScale();
|
spinBoxValue = mGizmo.TotalScale();
|
||||||
else if (!mSelection.empty())
|
else if (!mSelection.empty())
|
||||||
spinBoxValue = mSelection.front()->LocalScale();
|
spinBoxValue = mSelection.front()->AbsoluteScale();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ void CWorldEditor::UpdateCameraOrbit()
|
||||||
if (!mSelection.isEmpty())
|
if (!mSelection.isEmpty())
|
||||||
pCamera->SetOrbit(mSelectionBounds);
|
pCamera->SetOrbit(mSelectionBounds);
|
||||||
else if (mpArea)
|
else if (mpArea)
|
||||||
pCamera->SetOrbit(mpArea->AABox(), 0.8f);
|
pCamera->SetOrbit(mpArea->AABox(), 1.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorldEditor::OnCameraSpeedChange(double speed)
|
void CWorldEditor::OnCameraSpeedChange(double speed)
|
||||||
|
@ -325,7 +325,7 @@ void CWorldEditor::OnTransformSpinBoxModified(CVector3f value)
|
||||||
|
|
||||||
case CGizmo::eScale:
|
case CGizmo::eScale:
|
||||||
{
|
{
|
||||||
CVector3f delta = value / mSelection.front()->LocalScale();
|
CVector3f delta = value / mSelection.front()->AbsoluteScale();
|
||||||
mUndoStack.push(new CScaleNodeCommand(this, mSelection, CVector3f::skZero, delta));
|
mUndoStack.push(new CScaleNodeCommand(this, mSelection, CVector3f::skZero, delta));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue