Initial commit
This commit is contained in:
572
engines/hpl1/engine/math/BoundingVolume.cpp
Normal file
572
engines/hpl1/engine/math/BoundingVolume.cpp
Normal file
@@ -0,0 +1,572 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/math/BoundingVolume.h"
|
||||
|
||||
#include "hpl1/engine/graphics/LowLevelGraphics.h"
|
||||
#include "hpl1/engine/math/Math.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
static constexpr cTriEdge kvBVEdges[12] = {
|
||||
cTriEdge(1, 0, 0, 2),
|
||||
cTriEdge(3, 1, 0, 5),
|
||||
cTriEdge(2, 3, 0, 3),
|
||||
cTriEdge(0, 2, 0, 4),
|
||||
|
||||
cTriEdge(0, 4, 4, 2),
|
||||
cTriEdge(4, 6, 4, 1),
|
||||
cTriEdge(6, 2, 4, 3),
|
||||
cTriEdge(4, 5, 1, 2),
|
||||
|
||||
cTriEdge(5, 7, 1, 5),
|
||||
cTriEdge(7, 6, 1, 3),
|
||||
cTriEdge(1, 5, 2, 5),
|
||||
cTriEdge(3, 7, 5, 3)};
|
||||
|
||||
static constexpr cVector3f globalNormals[6] = {
|
||||
cVector3f(1, 0, 0),
|
||||
cVector3f(-1, 0, 0),
|
||||
|
||||
cVector3f(0, 1, 0),
|
||||
cVector3f(0, -1, 0),
|
||||
|
||||
cVector3f(0, 0, 1),
|
||||
cVector3f(0, 0, -1)};
|
||||
|
||||
static bool globalfacingLight[6] = {false, false, false, false, false, false};
|
||||
|
||||
static const int kvFacePoints[6] = {0, 5, 5, 6, 4, 7};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SHADOW VOLUME
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cShadowVolumeBV::CollideBoundingVolume(cBoundingVolume *aBV) {
|
||||
// Do a simple sphere collide test
|
||||
if (CollideBVSphere(aBV) == false)
|
||||
return false;
|
||||
|
||||
return CollideBVAABB(aBV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cShadowVolumeBV::CollideBVSphere(cBoundingVolume *aBV) {
|
||||
for (int i = 0; i < mlPlaneCount; ++i) {
|
||||
float fDist = cMath::PlaneToPointDist(mvPlanes[i], aBV->GetWorldCenter());
|
||||
|
||||
if (fDist < -aBV->GetRadius()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cShadowVolumeBV::CollideBVAABB(cBoundingVolume *aBV) {
|
||||
cVector3f vMax = aBV->GetMax();
|
||||
cVector3f vMin = aBV->GetMin();
|
||||
|
||||
// Get the corners from the AAB
|
||||
cVector3f vCorners[9] = {
|
||||
cVector3f(vMax.x, vMax.y, vMax.z),
|
||||
cVector3f(vMax.x, vMax.y, vMin.z),
|
||||
cVector3f(vMax.x, vMin.y, vMax.z),
|
||||
cVector3f(vMax.x, vMin.y, vMin.z),
|
||||
|
||||
cVector3f(vMin.x, vMax.y, vMax.z),
|
||||
cVector3f(vMin.x, vMax.y, vMin.z),
|
||||
cVector3f(vMin.x, vMin.y, vMax.z),
|
||||
cVector3f(vMin.x, vMin.y, vMin.z),
|
||||
|
||||
// The "fuling", add center as well...
|
||||
aBV->GetPosition()};
|
||||
|
||||
// Go through all the planes
|
||||
for (int i = 0; i < mlPlaneCount; i++) {
|
||||
int lInCount = 9;
|
||||
// bool bIsIn = true;
|
||||
|
||||
for (int j = 0; j < 9; j++) {
|
||||
float fDist = cMath::PlaneToPointDist(mvPlanes[i], vCorners[j]);
|
||||
if (fDist < 0) {
|
||||
lInCount--;
|
||||
// bIsIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (lInCount == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cBoundingVolume::cBoundingVolume() {
|
||||
m_mtxTransform = cMatrixf::Identity;
|
||||
|
||||
mvLocalMax = 0;
|
||||
mvLocalMin = 0;
|
||||
|
||||
mvPosition = 0;
|
||||
mvPivot = 0;
|
||||
mvSize = 0;
|
||||
mfRadius = 0;
|
||||
|
||||
mbPositionUpdated = true;
|
||||
mbSizeUpdated = true;
|
||||
|
||||
mShadowVolume.mvPoints.reserve(8 * 4);
|
||||
mbShadowPlanesNeedUpdate = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cVector3f cBoundingVolume::GetMax() {
|
||||
UpdateSize();
|
||||
return mvWorldMax;
|
||||
}
|
||||
|
||||
cVector3f cBoundingVolume::GetMin() {
|
||||
UpdateSize();
|
||||
return mvWorldMin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cVector3f cBoundingVolume::GetLocalMax() {
|
||||
return mvLocalMax;
|
||||
}
|
||||
|
||||
cVector3f cBoundingVolume::GetLocalMin() {
|
||||
return mvLocalMin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cBoundingVolume::SetLocalMinMax(const cVector3f &avMin, const cVector3f &avMax) {
|
||||
mvLocalMax = avMax;
|
||||
mvLocalMin = avMin;
|
||||
|
||||
mbSizeUpdated = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cVector3f cBoundingVolume::GetLocalCenter() {
|
||||
return mvPivot;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cVector3f cBoundingVolume::GetWorldCenter() {
|
||||
UpdateSize();
|
||||
|
||||
return m_mtxTransform.GetTranslation() + mvPivot;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cBoundingVolume::SetPosition(const cVector3f &avPos) {
|
||||
m_mtxTransform.SetTranslation(avPos);
|
||||
|
||||
mbPositionUpdated = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cVector3f cBoundingVolume::GetPosition() {
|
||||
return m_mtxTransform.GetTranslation();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cBoundingVolume::SetTransform(const cMatrixf &a_mtxTransform) {
|
||||
m_mtxTransform = a_mtxTransform;
|
||||
|
||||
mbSizeUpdated = true;
|
||||
}
|
||||
|
||||
const cMatrixf &cBoundingVolume::GetTransform() {
|
||||
return m_mtxTransform;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cBoundingVolume::SetSize(const cVector3f &avSize) {
|
||||
mvLocalMax = avSize * 0.5;
|
||||
mvLocalMin = avSize * -0.5;
|
||||
|
||||
mbSizeUpdated = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cVector3f cBoundingVolume::GetSize() {
|
||||
UpdateSize();
|
||||
|
||||
return mvSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
float cBoundingVolume::GetRadius() {
|
||||
UpdateSize();
|
||||
|
||||
return mfRadius;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cShadowVolumeBV *cBoundingVolume::GetShadowVolume(const cVector3f &avLightPos,
|
||||
float afLightRange, bool abForceUpdate) {
|
||||
if (cMath::PointBVCollision(avLightPos, *this))
|
||||
return NULL;
|
||||
|
||||
if (!abForceUpdate && !mbShadowPlanesNeedUpdate)
|
||||
return &mShadowVolume;
|
||||
|
||||
// Set size 0.
|
||||
mShadowVolume.mvPoints.resize(0);
|
||||
|
||||
// Get the corners.
|
||||
cVector3f vMax = GetMax();
|
||||
cVector3f vMin = GetMin();
|
||||
cVector3f vCorners[8];
|
||||
vCorners[0] = cVector3f(vMax.x, vMax.y, vMax.z);
|
||||
vCorners[1] = cVector3f(vMax.x, vMax.y, vMin.z);
|
||||
vCorners[2] = cVector3f(vMax.x, vMin.y, vMax.z);
|
||||
vCorners[3] = cVector3f(vMax.x, vMin.y, vMin.z);
|
||||
|
||||
vCorners[4] = cVector3f(vMin.x, vMax.y, vMax.z);
|
||||
vCorners[5] = cVector3f(vMin.x, vMax.y, vMin.z);
|
||||
vCorners[6] = cVector3f(vMin.x, vMin.y, vMax.z);
|
||||
vCorners[7] = cVector3f(vMin.x, vMin.y, vMin.z);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Iterate the faces and check which ones are facing the light.
|
||||
// int lNearPoint = -1;
|
||||
mShadowVolume.mlPlaneCount = 0;
|
||||
for (int face = 0; face < 6; face++) {
|
||||
globalfacingLight[face] = cMath::Vector3Dot(globalNormals[face],
|
||||
vCorners[kvFacePoints[face]] - avLightPos) < 0;
|
||||
|
||||
// Get a point for the near plane. (any edge point will do)
|
||||
if (globalfacingLight[face]) {
|
||||
mShadowVolume.mvPlanes[mShadowVolume.mlPlaneCount] = cPlanef(
|
||||
globalNormals[face] * -1.0f, vCorners[kvFacePoints[face]]);
|
||||
mShadowVolume.mlPlaneCount++;
|
||||
}
|
||||
}
|
||||
|
||||
mShadowVolume.mlCapPlanes = mShadowVolume.mlPlaneCount;
|
||||
|
||||
// The direction a point is pushed away in
|
||||
cVector3f vDir;
|
||||
|
||||
// The length to push the shadow points.
|
||||
float fPushLength = afLightRange * kSqrt2f;
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// Iterate the edges and build quads from the silhouette
|
||||
for (int edge = 0; edge < 12; edge++) {
|
||||
const cTriEdge &Edge = kvBVEdges[edge];
|
||||
|
||||
const bool facingLight1 = globalfacingLight[Edge.tri1];
|
||||
const bool facingLight2 = globalfacingLight[Edge.tri2];
|
||||
|
||||
if ((facingLight1 && !facingLight2) || (facingLight2 && !facingLight1)) {
|
||||
if (facingLight1) {
|
||||
mShadowVolume.mvPoints.push_back(vCorners[Edge.point1]);
|
||||
mShadowVolume.mvPoints.push_back(vCorners[Edge.point2]);
|
||||
|
||||
vDir = (vCorners[Edge.point2] - avLightPos);
|
||||
vDir.Normalise();
|
||||
mShadowVolume.mvPoints.push_back(vCorners[Edge.point2] + vDir * fPushLength);
|
||||
|
||||
vDir = (vCorners[Edge.point1] - avLightPos);
|
||||
vDir.Normalise();
|
||||
mShadowVolume.mvPoints.push_back(vCorners[Edge.point1] + vDir * fPushLength);
|
||||
} else {
|
||||
mShadowVolume.mvPoints.push_back(vCorners[Edge.point2]);
|
||||
mShadowVolume.mvPoints.push_back(vCorners[Edge.point1]);
|
||||
|
||||
vDir = (vCorners[Edge.point1] - avLightPos);
|
||||
vDir.Normalise();
|
||||
mShadowVolume.mvPoints.push_back(vCorners[Edge.point1] + vDir * fPushLength);
|
||||
|
||||
vDir = (vCorners[Edge.point2] - avLightPos);
|
||||
vDir.Normalise();
|
||||
mShadowVolume.mvPoints.push_back(vCorners[Edge.point2] + vDir * fPushLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
// Create the side planes:
|
||||
|
||||
for (int i = 0; i < (int)mShadowVolume.mvPoints.size(); i += 4) {
|
||||
// Normal should point inwards
|
||||
cVector3f vNormal = cMath::Vector3Cross(
|
||||
mShadowVolume.mvPoints[i + 1] - mShadowVolume.mvPoints[i + 0],
|
||||
mShadowVolume.mvPoints[i + 2] - mShadowVolume.mvPoints[i + 0]);
|
||||
mShadowVolume.mvPlanes[mShadowVolume.mlPlaneCount].FromNormalPoint(vNormal,
|
||||
mShadowVolume.mvPoints[i + 0]);
|
||||
mShadowVolume.mvPlanes[mShadowVolume.mlPlaneCount].Normalise();
|
||||
|
||||
mShadowVolume.mlPlaneCount++;
|
||||
}
|
||||
|
||||
return &mShadowVolume;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cBoundingVolume::DrawEdges(const cVector3f &avLightPos, float afLightRange, iLowLevelGraphics *apLowLevelGraphics) {
|
||||
cShadowVolumeBV *pVolume = GetShadowVolume(avLightPos, afLightRange, false);
|
||||
|
||||
apLowLevelGraphics->SetBlendActive(true);
|
||||
apLowLevelGraphics->SetBlendFunc(eBlendFunc_One, eBlendFunc_One);
|
||||
apLowLevelGraphics->SetDepthWriteActive(false);
|
||||
tVertexVec vVtx;
|
||||
vVtx.resize(4);
|
||||
|
||||
for (int capplane = 0; capplane < mShadowVolume.mlCapPlanes; capplane++) {
|
||||
mShadowVolume.mvPlanes[capplane].CalcNormal();
|
||||
apLowLevelGraphics->DrawLine(GetWorldCenter(), GetWorldCenter() + mShadowVolume.mvPlanes[capplane].normal * -0.5f, cColor(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
int lPlane = mShadowVolume.mlCapPlanes;
|
||||
for (int quad = 0; quad < (int)pVolume->mvPoints.size(); quad += 4) {
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
vVtx[i].pos = pVolume->mvPoints[quad + i];
|
||||
|
||||
apLowLevelGraphics->DrawQuad(vVtx, cColor(0.2f, 0, 0.2f));
|
||||
|
||||
cVector3f vCenter = (vVtx[1].pos + vVtx[0].pos) * 0.5f;
|
||||
mShadowVolume.mvPlanes[lPlane].CalcNormal();
|
||||
apLowLevelGraphics->DrawLine(vCenter, vCenter + mShadowVolume.mvPlanes[lPlane].normal * -0.5f, cColor(1, 1, 1, 1));
|
||||
lPlane++;
|
||||
}
|
||||
|
||||
apLowLevelGraphics->SetBlendActive(false);
|
||||
apLowLevelGraphics->SetDepthWriteActive(true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cBoundingVolume::AddArrayPoints(const float *apArray, int alNumOfVectors) {
|
||||
cBVTempArray temp;
|
||||
temp.mpArray = apArray;
|
||||
temp.mlSize = alNumOfVectors;
|
||||
|
||||
mlstArrays.push_back(temp);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cBoundingVolume::CreateFromPoints(int alStride) {
|
||||
mvLocalMax = cVector3f(-100000, -100000, -100000);
|
||||
mvLocalMin = cVector3f(100000, 100000, 100000);
|
||||
|
||||
for (tBVTempArrayListIt it = mlstArrays.begin(); it != mlstArrays.end(); it++) {
|
||||
// Loop through all the vectors and find min and max
|
||||
const float *apVec = it->mpArray;
|
||||
int lNumOfVectors = it->mlSize;
|
||||
while (lNumOfVectors) {
|
||||
// Min and max X
|
||||
if (apVec[0] < mvLocalMin.x)
|
||||
mvLocalMin.x = apVec[0];
|
||||
if (apVec[0] > mvLocalMax.x)
|
||||
mvLocalMax.x = apVec[0];
|
||||
|
||||
// Min and max Y
|
||||
if (apVec[1] < mvLocalMin.y)
|
||||
mvLocalMin.y = apVec[1];
|
||||
if (apVec[1] > mvLocalMax.y)
|
||||
mvLocalMax.y = apVec[1];
|
||||
|
||||
// Min and max Z
|
||||
if (apVec[2] < mvLocalMin.z)
|
||||
mvLocalMin.z = apVec[2];
|
||||
if (apVec[2] > mvLocalMax.z)
|
||||
mvLocalMax.z = apVec[2];
|
||||
|
||||
apVec += alStride;
|
||||
lNumOfVectors--;
|
||||
}
|
||||
}
|
||||
mlstArrays.clear();
|
||||
|
||||
// Update the used size
|
||||
mbPositionUpdated = true;
|
||||
mbSizeUpdated = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PRIVATE METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cBoundingVolume::UpdateSize() {
|
||||
if (mbSizeUpdated) {
|
||||
cMatrixf mtxRot = m_mtxTransform.GetRotation();
|
||||
|
||||
// Transform the local corners
|
||||
cVector3f vCorners[8];
|
||||
vCorners[0] = cMath::MatrixMul(mtxRot, cVector3f(mvLocalMax.x, mvLocalMax.y, mvLocalMax.z));
|
||||
vCorners[1] = cMath::MatrixMul(mtxRot, cVector3f(mvLocalMax.x, mvLocalMax.y, mvLocalMin.z));
|
||||
vCorners[2] = cMath::MatrixMul(mtxRot, cVector3f(mvLocalMax.x, mvLocalMin.y, mvLocalMax.z));
|
||||
vCorners[3] = cMath::MatrixMul(mtxRot, cVector3f(mvLocalMax.x, mvLocalMin.y, mvLocalMin.z));
|
||||
|
||||
vCorners[4] = cMath::MatrixMul(mtxRot, cVector3f(mvLocalMin.x, mvLocalMax.y, mvLocalMax.z));
|
||||
vCorners[5] = cMath::MatrixMul(mtxRot, cVector3f(mvLocalMin.x, mvLocalMax.y, mvLocalMin.z));
|
||||
vCorners[6] = cMath::MatrixMul(mtxRot, cVector3f(mvLocalMin.x, mvLocalMin.y, mvLocalMax.z));
|
||||
vCorners[7] = cMath::MatrixMul(mtxRot, cVector3f(mvLocalMin.x, mvLocalMin.y, mvLocalMin.z));
|
||||
|
||||
mvMax = vCorners[0];
|
||||
mvMin = vCorners[0];
|
||||
|
||||
// Calculate the transformed min and max
|
||||
for (int i = 1; i < 8; i++) {
|
||||
// X
|
||||
if (vCorners[i].x < mvMin.x)
|
||||
mvMin.x = vCorners[i].x;
|
||||
else if (vCorners[i].x > mvMax.x)
|
||||
mvMax.x = vCorners[i].x;
|
||||
|
||||
// Y
|
||||
if (vCorners[i].y < mvMin.y)
|
||||
mvMin.y = vCorners[i].y;
|
||||
else if (vCorners[i].y > mvMax.y)
|
||||
mvMax.y = vCorners[i].y;
|
||||
|
||||
// Z
|
||||
if (vCorners[i].z < mvMin.z)
|
||||
mvMin.z = vCorners[i].z;
|
||||
else if (vCorners[i].z > mvMax.z)
|
||||
mvMax.z = vCorners[i].z;
|
||||
}
|
||||
|
||||
// Get the transformed size.
|
||||
mvSize = mvMax - mvMin;
|
||||
|
||||
// Get the local pivot (or offset from origo).
|
||||
mvPivot = mvMax - (mvSize * 0.5f);
|
||||
|
||||
// Get radius as pivot to localmax
|
||||
mfRadius = cMath::Vector3Dist(mvPivot, mvMax);
|
||||
|
||||
mbSizeUpdated = false;
|
||||
mbPositionUpdated = true;
|
||||
}
|
||||
|
||||
if (mbPositionUpdated) {
|
||||
mvWorldMax = m_mtxTransform.GetTranslation() + mvMax;
|
||||
mvWorldMin = m_mtxTransform.GetTranslation() + mvMin;
|
||||
|
||||
mbPositionUpdated = false;
|
||||
|
||||
mbShadowPlanesNeedUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SERIALIZE CLASS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
kBeginSerializeBase(cBoundingVolume)
|
||||
kSerializeVar(m_mtxTransform, eSerializeType_Matrixf)
|
||||
kSerializeVar(mvLocalMax, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvLocalMin, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvMax, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvMin, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvPivot, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvWorldMax, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvWorldMin, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvPosition, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvSize, eSerializeType_Vector3f)
|
||||
kSerializeVar(mfRadius, eSerializeType_Float32)
|
||||
kEndSerialize()
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/* OLD "NEAR PLANE CODE"
|
||||
int lNearPoint =-1;
|
||||
for(int face=0; face< 6; face++)
|
||||
{
|
||||
gvFaces[face].facingLight = cMath::Vector3Dot(gvFaces[face].normal,
|
||||
vCorners[kvFacePoints[face]] - avLightPos)<0;
|
||||
|
||||
//Get a point for the near plane. (any edge point will do)
|
||||
if(gvFaces[face].facingLight && lNearPoint<0)
|
||||
{
|
||||
lNearPoint = kvFacePoints[face];
|
||||
}
|
||||
}
|
||||
|
||||
//Build the near plane for the shadow.
|
||||
cVector3f vLightNormal = GetWorldCenter() - avLightPos;
|
||||
mShadowVolume.mvPlanes[0] = cPlanef(vLightNormal,vCorners[lNearPoint]);
|
||||
mShadowVolume.mvPlanes[0].Normalise();
|
||||
|
||||
|
||||
//The direction a point is pushed away in
|
||||
cVector3f vDir;
|
||||
|
||||
float fPushLength = afLightRange*kSqrt2f;
|
||||
|
||||
//The number of planes created.
|
||||
mShadowVolume.mlPlaneCount =1;*/
|
||||
} // namespace hpl
|
||||
135
engines/hpl1/engine/math/BoundingVolume.h
Normal file
135
engines/hpl1/engine/math/BoundingVolume.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_BOUNDING_VOLUME_H
|
||||
#define HPL_BOUNDING_VOLUME_H
|
||||
|
||||
#include "hpl1/engine/graphics/GraphicsTypes.h"
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
#include "hpl1/engine/system/SerializeClass.h"
|
||||
#include "hpl1/engine/system/SystemTypes.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
class iLowLevelGraphics;
|
||||
class cBoundingVolume;
|
||||
|
||||
class cBVTempArray {
|
||||
public:
|
||||
const float *mpArray;
|
||||
int mlSize;
|
||||
};
|
||||
|
||||
enum eBVCollision {
|
||||
eBVCollision_Inside,
|
||||
eBVCollision_Outside,
|
||||
eBVCollision_Intersect,
|
||||
eBVCollision_LastEnum
|
||||
};
|
||||
|
||||
typedef Common::List<cBVTempArray> tBVTempArrayList;
|
||||
typedef tBVTempArrayList::iterator tBVTempArrayListIt;
|
||||
|
||||
class cShadowVolumeBV {
|
||||
public:
|
||||
cPlanef mvPlanes[12];
|
||||
int mlPlaneCount;
|
||||
tVector3fVec mvPoints;
|
||||
int mlCapPlanes;
|
||||
|
||||
bool CollideBoundingVolume(cBoundingVolume *aBV);
|
||||
|
||||
private:
|
||||
bool CollideBVSphere(cBoundingVolume *aBV);
|
||||
bool CollideBVAABB(cBoundingVolume *aBV);
|
||||
};
|
||||
|
||||
class cBoundingVolume : public iSerializable {
|
||||
friend class cMath;
|
||||
kSerializableClassInit(cBoundingVolume) public : cBoundingVolume();
|
||||
|
||||
cVector3f GetMax();
|
||||
cVector3f GetMin();
|
||||
|
||||
cVector3f GetLocalMax();
|
||||
cVector3f GetLocalMin();
|
||||
|
||||
void SetLocalMinMax(const cVector3f &mvMin, const cVector3f &mvMax);
|
||||
|
||||
void SetPosition(const cVector3f &avPos);
|
||||
cVector3f GetPosition();
|
||||
|
||||
void SetSize(const cVector3f &avSize);
|
||||
cVector3f GetSize();
|
||||
|
||||
void SetTransform(const cMatrixf &a_mtxTransform);
|
||||
const cMatrixf &GetTransform();
|
||||
|
||||
cVector3f GetLocalCenter();
|
||||
cVector3f GetWorldCenter();
|
||||
|
||||
float GetRadius();
|
||||
|
||||
void AddArrayPoints(const float *apArray, int alNumOfVectors);
|
||||
void CreateFromPoints(int alStride);
|
||||
|
||||
cShadowVolumeBV *GetShadowVolume(const cVector3f &avLightPos, float afLightRange, bool abForceUpdate);
|
||||
|
||||
// Debug:
|
||||
void DrawEdges(const cVector3f &avLightPos, float afLightRange, iLowLevelGraphics *apLowLevelGraphics);
|
||||
void UpdateSize();
|
||||
|
||||
cMatrixf m_mtxTransform;
|
||||
|
||||
cVector3f mvLocalMax;
|
||||
cVector3f mvLocalMin;
|
||||
|
||||
cVector3f mvMax;
|
||||
cVector3f mvMin;
|
||||
|
||||
cVector3f mvPivot;
|
||||
|
||||
cVector3f mvWorldMax;
|
||||
cVector3f mvWorldMin;
|
||||
|
||||
cVector3f mvPosition;
|
||||
cVector3f mvSize;
|
||||
float mfRadius;
|
||||
|
||||
private:
|
||||
bool mbPositionUpdated;
|
||||
bool mbSizeUpdated;
|
||||
|
||||
tBVTempArrayList mlstArrays;
|
||||
|
||||
cShadowVolumeBV mShadowVolume;
|
||||
bool mbShadowPlanesNeedUpdate;
|
||||
};
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_BOUNDING_VOLUME_H
|
||||
412
engines/hpl1/engine/math/Frustum.cpp
Normal file
412
engines/hpl1/engine/math/Frustum.cpp
Normal file
@@ -0,0 +1,412 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/math/Frustum.h"
|
||||
|
||||
#include "hpl1/engine/graphics/LowLevelGraphics.h"
|
||||
#include "hpl1/engine/math/Math.h"
|
||||
#include "hpl1/engine/system/low_level_system.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cFrustum::cFrustum() {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cFrustum::SetViewProjMatrix(const cMatrixf &a_mtxProj, const cMatrixf &a_mtxView,
|
||||
float afFarPlane, float afNearPlane, float afFOV, float afAspect,
|
||||
const cVector3f &avOrigin, bool abInfFarPlane) {
|
||||
m_mtxViewProj = cMath::MatrixMul(a_mtxProj, a_mtxView);
|
||||
m_mtxModelView = a_mtxView;
|
||||
|
||||
mfFarPlane = afFarPlane;
|
||||
mfNearPlane = afNearPlane;
|
||||
mfFOV = afFOV;
|
||||
mfAspect = afAspect;
|
||||
|
||||
mvOrigin = avOrigin;
|
||||
|
||||
mbInfFarPlane = abInfFarPlane;
|
||||
|
||||
// This could be made more accurate.
|
||||
mOriginBV.SetSize(afNearPlane * 2);
|
||||
mOriginBV.SetPosition(mvOrigin);
|
||||
|
||||
UpdatePlanes();
|
||||
UpdateSphere();
|
||||
UpdateEndPoints();
|
||||
UpdateBV();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cPlanef cFrustum::GetPlane(eFrustumPlane aType) {
|
||||
return mPlane[aType];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
eFrustumCollision cFrustum::CollideBoundingVolume(cBoundingVolume *aBV) {
|
||||
// Check if the BV is in the Frustum sphere.
|
||||
if (CollideFustrumSphere(aBV) == eFrustumCollision_Outside) {
|
||||
return eFrustumCollision_Outside;
|
||||
}
|
||||
|
||||
// Do a simple sphere collide test
|
||||
eFrustumCollision ret = CollideBVSphere(aBV);
|
||||
|
||||
// If there was an intersection, collide with the AABB
|
||||
if (ret == eFrustumCollision_Intersect) {
|
||||
return CollideBVAABB(aBV);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cFrustum::CheckLineIntersection(const cVector3f &avPoint1, const cVector3f &avPoint2) {
|
||||
return cMath::CheckFrustumLineIntersection(&mPlane[0], avPoint1, avPoint2, 3);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cFrustum::CheckQuadMeshIntersection(tVector3fVec *apPoints) {
|
||||
return cMath::CheckFrustumQuadMeshIntersection(&mPlane[0], apPoints, 3);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cFrustum::CheckVolumeIntersection(cShadowVolumeBV *apVolume) {
|
||||
if (CheckQuadMeshIntersection(&apVolume->mvPoints)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The first shadow plane is the near plane which we can skip.
|
||||
int lPairNum = (apVolume->mlPlaneCount - 1) / 2;
|
||||
|
||||
// Check with volume planes.
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (cMath::CheckFrustumLineIntersection(&apVolume->mvPlanes[1], mvOrigin, mvEndPoints[i],
|
||||
lPairNum)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PRIVATE METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
eFrustumCollision cFrustum::CollideFustrumSphere(cBoundingVolume *aBV) {
|
||||
float fRadiusSum = mBoundingSphere.r + aBV->GetRadius();
|
||||
cVector3f vSepAxis = mBoundingSphere.center - aBV->GetWorldCenter();
|
||||
if (vSepAxis.SqrLength() > (fRadiusSum * fRadiusSum)) {
|
||||
return eFrustumCollision_Outside;
|
||||
}
|
||||
|
||||
return eFrustumCollision_Intersect;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
eFrustumCollision cFrustum::CollideBVSphere(cBoundingVolume *aBV) {
|
||||
int lPlanes = 6;
|
||||
if (mbInfFarPlane)
|
||||
lPlanes = 5;
|
||||
|
||||
for (int i = 0; i < lPlanes; i++) {
|
||||
float fDist = cMath::PlaneToPointDist(mPlane[i], aBV->GetWorldCenter());
|
||||
|
||||
if (fDist < -aBV->GetRadius()) {
|
||||
return eFrustumCollision_Outside;
|
||||
}
|
||||
|
||||
if (ABS(fDist) < aBV->GetRadius()) {
|
||||
return eFrustumCollision_Intersect;
|
||||
}
|
||||
}
|
||||
|
||||
return eFrustumCollision_Inside;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
eFrustumCollision cFrustum::CollideBVAABB(cBoundingVolume *aBV) {
|
||||
cVector3f vMax = aBV->GetMax();
|
||||
cVector3f vMin = aBV->GetMin();
|
||||
|
||||
// Get the corners from the AAB
|
||||
cVector3f vCorners[9] = {
|
||||
cVector3f(vMax.x, vMax.y, vMax.z),
|
||||
cVector3f(vMax.x, vMax.y, vMin.z),
|
||||
cVector3f(vMax.x, vMin.y, vMax.z),
|
||||
cVector3f(vMax.x, vMin.y, vMin.z),
|
||||
|
||||
cVector3f(vMin.x, vMax.y, vMax.z),
|
||||
cVector3f(vMin.x, vMax.y, vMin.z),
|
||||
cVector3f(vMin.x, vMin.y, vMax.z),
|
||||
cVector3f(vMin.x, vMin.y, vMin.z),
|
||||
|
||||
// The "fuling", add center as well...
|
||||
aBV->GetPosition()};
|
||||
|
||||
int lTotalIn = 0;
|
||||
|
||||
int lPlanes = 6;
|
||||
if (mbInfFarPlane)
|
||||
lPlanes = 5;
|
||||
|
||||
// Go through all the planes
|
||||
for (int i = 0; i < lPlanes; i++) {
|
||||
int lInCount = 9;
|
||||
bool bIsIn = true;
|
||||
|
||||
for (int j = 0; j < 9; j++) {
|
||||
float fDist = cMath::PlaneToPointDist(mPlane[i], vCorners[j]);
|
||||
if (fDist < 0) {
|
||||
lInCount--;
|
||||
bIsIn = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (lInCount == 0)
|
||||
return eFrustumCollision_Outside;
|
||||
if (bIsIn)
|
||||
lTotalIn++;
|
||||
}
|
||||
|
||||
if (lTotalIn == lPlanes)
|
||||
return eFrustumCollision_Inside;
|
||||
|
||||
return eFrustumCollision_Intersect;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cFrustum::UpdateSphere() {
|
||||
// calculate the radius of the frustum sphere
|
||||
float fViewLen = mfFarPlane - mfNearPlane;
|
||||
|
||||
float fHeight = fViewLen * tan(mfFOV * 0.5f);
|
||||
float fWidth = fHeight * mfAspect;
|
||||
|
||||
// halfway point between near/far planes starting at the origin and extending along the z axis
|
||||
cVector3f P(0.0f, 0.0f, mfNearPlane + fViewLen * 0.5f);
|
||||
|
||||
// the calculate far corner of the frustum
|
||||
cVector3f Q(fWidth, fHeight, fViewLen);
|
||||
|
||||
// the vector between P and Q
|
||||
cVector3f vDiff = P - Q;
|
||||
|
||||
// the radius becomes the length of this vector
|
||||
float fRadius = vDiff.Length();
|
||||
|
||||
// get the look vector of the camera from the view matrix
|
||||
cVector3f vLookVector = m_mtxModelView.GetForward() * -1;
|
||||
|
||||
// calculate the center of the sphere
|
||||
cVector3f vCenter = (mvOrigin) + (vLookVector * (fViewLen * 0.5f + mfNearPlane));
|
||||
|
||||
mBoundingSphere = cSpheref(vCenter, fRadius);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cFrustum::UpdatePlanes() {
|
||||
// Left
|
||||
mPlane[eFrustumPlane_Left] = cPlanef(m_mtxViewProj.m[3][0] + m_mtxViewProj.m[0][0],
|
||||
m_mtxViewProj.m[3][1] + m_mtxViewProj.m[0][1],
|
||||
m_mtxViewProj.m[3][2] + m_mtxViewProj.m[0][2],
|
||||
m_mtxViewProj.m[3][3] + m_mtxViewProj.m[0][3]);
|
||||
|
||||
// Right
|
||||
mPlane[eFrustumPlane_Right] = cPlanef(m_mtxViewProj.m[3][0] - m_mtxViewProj.m[0][0],
|
||||
m_mtxViewProj.m[3][1] - m_mtxViewProj.m[0][1],
|
||||
m_mtxViewProj.m[3][2] - m_mtxViewProj.m[0][2],
|
||||
m_mtxViewProj.m[3][3] - m_mtxViewProj.m[0][3]);
|
||||
|
||||
// Bottom
|
||||
mPlane[eFrustumPlane_Bottom] = cPlanef(m_mtxViewProj.m[3][0] + m_mtxViewProj.m[1][0],
|
||||
m_mtxViewProj.m[3][1] + m_mtxViewProj.m[1][1],
|
||||
m_mtxViewProj.m[3][2] + m_mtxViewProj.m[1][2],
|
||||
m_mtxViewProj.m[3][3] + m_mtxViewProj.m[1][3]);
|
||||
|
||||
// Top
|
||||
mPlane[eFrustumPlane_Top] = cPlanef(m_mtxViewProj.m[3][0] - m_mtxViewProj.m[1][0],
|
||||
m_mtxViewProj.m[3][1] - m_mtxViewProj.m[1][1],
|
||||
m_mtxViewProj.m[3][2] - m_mtxViewProj.m[1][2],
|
||||
m_mtxViewProj.m[3][3] - m_mtxViewProj.m[1][3]);
|
||||
|
||||
// Near
|
||||
mPlane[eFrustumPlane_Near] = cPlanef(m_mtxViewProj.m[3][0] + m_mtxViewProj.m[2][0],
|
||||
m_mtxViewProj.m[3][1] + m_mtxViewProj.m[2][1],
|
||||
m_mtxViewProj.m[3][2] + m_mtxViewProj.m[2][2],
|
||||
m_mtxViewProj.m[3][3] + m_mtxViewProj.m[2][3]);
|
||||
// Far
|
||||
mPlane[eFrustumPlane_Far] = cPlanef(m_mtxViewProj.m[3][0] - m_mtxViewProj.m[2][0],
|
||||
m_mtxViewProj.m[3][1] - m_mtxViewProj.m[2][1],
|
||||
m_mtxViewProj.m[3][2] - m_mtxViewProj.m[2][2],
|
||||
m_mtxViewProj.m[3][3] - m_mtxViewProj.m[2][3]);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
mPlane[i].Normalise();
|
||||
mPlane[i].CalcNormal();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cFrustum::UpdateEndPoints() {
|
||||
float fXAngle = mfFOV * 0.5f;
|
||||
float fYAngle = mfFOV * 0.5f * mfAspect;
|
||||
|
||||
cVector3f vForward = m_mtxModelView.GetForward();
|
||||
// cVector3f vUp = m_mtxModelView.GetUp();
|
||||
cVector3f vRight = m_mtxModelView.GetRight();
|
||||
|
||||
// Point the forward vec in different dirs.
|
||||
cVector3f vUpDir = cMath::MatrixMul(cMath::MatrixQuaternion(cQuaternion(fXAngle, vRight)), vForward);
|
||||
cVector3f vDownDir = cMath::MatrixMul(cMath::MatrixQuaternion(cQuaternion(-fXAngle, vRight)), vForward);
|
||||
|
||||
// cVector3f vRightDir = cMath::MatrixMul(cMath::MatrixQuaternion(cQuaternion(fYAngle,vUp)), vForward);
|
||||
// cVector3f vLeftDir = cMath::MatrixMul(cMath::MatrixQuaternion(cQuaternion(-fYAngle,vUp)), vForward);
|
||||
|
||||
vForward = vForward * -1;
|
||||
|
||||
float fRightAdd = sin(fYAngle);
|
||||
// float fUpAdd = sin(fXAngle);
|
||||
|
||||
cVector3f vVec0 = vUpDir + vRight * fRightAdd;
|
||||
cVector3f vVec2 = vDownDir + vRight * fRightAdd;
|
||||
cVector3f vVec3 = vDownDir + vRight * -fRightAdd;
|
||||
cVector3f vVec1 = vUpDir + vRight * -fRightAdd;
|
||||
|
||||
/*cVector3f vVec0 = vUpDir;//cMath::Vector3Normalize(vUpDir+vRightDir);
|
||||
cVector3f vVec1 = vRightDir;//cMath::Vector3Normalize(vUpDir+vLeftDir);
|
||||
cVector3f vVec2 = vDownDir;//cMath::Vector3Normalize(vDownDir+vLeftDir);
|
||||
cVector3f vVec3 = vLeftDir;//cMath::Vector3Normalize(vDownDir+vRightDir);*/
|
||||
|
||||
// angles between forward and the vectors
|
||||
float fAngle0 = cMath::Vector3Angle(vVec0, vForward);
|
||||
float fAngle1 = cMath::Vector3Angle(vVec1, vForward);
|
||||
float fAngle2 = cMath::Vector3Angle(vVec2, vForward);
|
||||
float fAngle3 = cMath::Vector3Angle(vVec3, vForward);
|
||||
|
||||
// create end points.
|
||||
mvEndPoints[0] = mvOrigin + vVec0 * (mfFarPlane / cos(fAngle0));
|
||||
mvEndPoints[1] = mvOrigin + vVec1 * (mfFarPlane / cos(fAngle1));
|
||||
mvEndPoints[2] = mvOrigin + vVec2 * (mfFarPlane / cos(fAngle2));
|
||||
mvEndPoints[3] = mvOrigin + vVec3 * (mfFarPlane / cos(fAngle3));
|
||||
|
||||
/*mvEndPoints[0] = mvOrigin + (vUpDir+vRightDir) * mfFarPlane *-1;
|
||||
mvEndPoints[1] = mvOrigin + (vUpDir+vLeftDir) * mfFarPlane*-1;
|
||||
mvEndPoints[2] = mvOrigin + (vDownDir+vRightDir)* mfFarPlane*-1;
|
||||
mvEndPoints[3] = mvOrigin + (vDownDir+vLeftDir) * mfFarPlane*-1;*/
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cFrustum::UpdateBV() {
|
||||
cVector3f vMin = mvOrigin;
|
||||
cVector3f vMax = mvOrigin;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (vMax.x < mvEndPoints[i].x)
|
||||
vMax.x = mvEndPoints[i].x;
|
||||
else if (vMin.x > mvEndPoints[i].x)
|
||||
vMin.x = mvEndPoints[i].x;
|
||||
|
||||
if (vMax.y < mvEndPoints[i].y)
|
||||
vMax.y = mvEndPoints[i].y;
|
||||
else if (vMin.y > mvEndPoints[i].y)
|
||||
vMin.y = mvEndPoints[i].y;
|
||||
|
||||
if (vMax.z < mvEndPoints[i].z)
|
||||
vMax.z = mvEndPoints[i].z;
|
||||
else if (vMin.z > mvEndPoints[i].z)
|
||||
vMin.z = mvEndPoints[i].z;
|
||||
}
|
||||
|
||||
mBoundingVolume.SetLocalMinMax(vMin, vMax);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const cVector3f &cFrustum::GetOrigin() {
|
||||
return mvOrigin;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cBoundingVolume *cFrustum::GetOriginBV() {
|
||||
return &mOriginBV;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cVector3f cFrustum::GetForward() {
|
||||
return m_mtxModelView.GetForward();
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cFrustum::Draw(iLowLevelGraphics *apLowLevelGraphics) {
|
||||
apLowLevelGraphics->DrawLine(mvOrigin, mvEndPoints[0], cColor(1, 1, 1, 1));
|
||||
apLowLevelGraphics->DrawLine(mvOrigin, mvEndPoints[1], cColor(1, 1, 1, 1));
|
||||
apLowLevelGraphics->DrawLine(mvOrigin, mvEndPoints[2], cColor(1, 1, 1, 1));
|
||||
apLowLevelGraphics->DrawLine(mvOrigin, mvEndPoints[3], cColor(1, 1, 1, 1));
|
||||
|
||||
apLowLevelGraphics->DrawLine(mvEndPoints[0], mvEndPoints[1], cColor(1, 1, 1, 1));
|
||||
apLowLevelGraphics->DrawLine(mvEndPoints[1], mvEndPoints[2], cColor(1, 1, 1, 1));
|
||||
apLowLevelGraphics->DrawLine(mvEndPoints[2], mvEndPoints[3], cColor(1, 1, 1, 1));
|
||||
apLowLevelGraphics->DrawLine(mvEndPoints[3], mvEndPoints[0], cColor(1, 1, 1, 1));
|
||||
|
||||
apLowLevelGraphics->DrawLine(mvEndPoints[0], mvEndPoints[2], cColor(1, 1, 1, 1));
|
||||
apLowLevelGraphics->DrawLine(mvEndPoints[1], mvEndPoints[3], cColor(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
} // namespace hpl
|
||||
125
engines/hpl1/engine/math/Frustum.h
Normal file
125
engines/hpl1/engine/math/Frustum.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_FRUSTUM_H
|
||||
#define HPL_FRUSTUM_H
|
||||
|
||||
#include "hpl1/engine/graphics/GraphicsTypes.h"
|
||||
#include "hpl1/engine/math/BoundingVolume.h"
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
#include "hpl1/engine/system/SystemTypes.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
class iLowLevelGraphics;
|
||||
|
||||
enum eFrustumPlane {
|
||||
eFrustumPlane_Left = 0,
|
||||
eFrustumPlane_Right = 1,
|
||||
eFrustumPlane_Bottom = 2,
|
||||
eFrustumPlane_Top = 3,
|
||||
eFrustumPlane_Near = 4,
|
||||
eFrustumPlane_Far = 5,
|
||||
eFrustumPlane_LastEnum = 7,
|
||||
};
|
||||
|
||||
enum eFrustumCollision {
|
||||
eFrustumCollision_Inside,
|
||||
eFrustumCollision_Outside,
|
||||
eFrustumCollision_Intersect,
|
||||
eFrustumCollision_LastEnum
|
||||
};
|
||||
|
||||
class cFrustum {
|
||||
public:
|
||||
cFrustum();
|
||||
|
||||
void SetViewProjMatrix(const cMatrixf &a_mtxProj, const cMatrixf &a_mtxView,
|
||||
float afFarPlane, float afNearPlane, float afFOV, float afAspect,
|
||||
const cVector3f &avOrigin, bool abInfFarPlane = false);
|
||||
|
||||
cPlanef GetPlane(eFrustumPlane aType);
|
||||
|
||||
eFrustumCollision CollideBoundingVolume(cBoundingVolume *aBV);
|
||||
|
||||
eFrustumCollision CollideFustrumSphere(cBoundingVolume *aBV);
|
||||
|
||||
eFrustumCollision CollideBVSphere(cBoundingVolume *aBV);
|
||||
eFrustumCollision CollideBVAABB(cBoundingVolume *aBV);
|
||||
|
||||
/**
|
||||
* Checks intersection with a line
|
||||
*/
|
||||
bool CheckLineIntersection(const cVector3f &avPoint1, const cVector3f &avPoint2);
|
||||
|
||||
/**
|
||||
* Checks intersection with a quad mesh.
|
||||
* \param apPoints the points of the quad mesh, every 4 points is a face.
|
||||
*/
|
||||
bool CheckQuadMeshIntersection(tVector3fVec *apPoints);
|
||||
|
||||
bool CheckVolumeIntersection(cShadowVolumeBV *apVolume);
|
||||
|
||||
cSpheref GetBoundingSphere() { return mBoundingSphere; }
|
||||
const cBoundingVolume &GetBoundingVolume() { return mBoundingVolume; }
|
||||
|
||||
const cVector3f &GetOrigin();
|
||||
cBoundingVolume *GetOriginBV();
|
||||
|
||||
cVector3f GetForward();
|
||||
|
||||
void Draw(iLowLevelGraphics *apLowLevelGraphics);
|
||||
|
||||
private:
|
||||
void UpdatePlanes();
|
||||
void UpdateSphere();
|
||||
void UpdateEndPoints();
|
||||
void UpdateBV();
|
||||
|
||||
float mfFarPlane;
|
||||
float mfNearPlane;
|
||||
float mfAspect;
|
||||
float mfFOV;
|
||||
|
||||
bool mbInfFarPlane;
|
||||
|
||||
cVector3f mvOrigin;
|
||||
cBoundingVolume mOriginBV;
|
||||
|
||||
cMatrixf m_mtxViewProj;
|
||||
cMatrixf m_mtxModelView;
|
||||
cPlanef mPlane[6];
|
||||
cSpheref mBoundingSphere;
|
||||
cBoundingVolume mBoundingVolume;
|
||||
|
||||
cVector3f mvEndPoints[4];
|
||||
tVector3fVec mvPoints;
|
||||
};
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_FRUSTUM_H
|
||||
1836
engines/hpl1/engine/math/Math.cpp
Normal file
1836
engines/hpl1/engine/math/Math.cpp
Normal file
File diff suppressed because it is too large
Load Diff
501
engines/hpl1/engine/math/Math.h
Normal file
501
engines/hpl1/engine/math/Math.h
Normal file
@@ -0,0 +1,501 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_MATH_H
|
||||
#define HPL_MATH_H
|
||||
|
||||
#include "hpl1/engine/math/BoundingVolume.h"
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
#include "hpl1/engine/math/MeshTypes.h"
|
||||
|
||||
#include "hpl1/engine/graphics/Color.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
class cMath {
|
||||
public:
|
||||
//////////////////////////////////////////////////////
|
||||
////////// RANDOM GENERATION ////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
/**
|
||||
* Generates a random integer from min to max
|
||||
* \param alMin
|
||||
* \param alMax
|
||||
* \return
|
||||
*/
|
||||
static int RandRectl(int alMin, int alMax);
|
||||
|
||||
/**
|
||||
* Generates a random float from min to max
|
||||
* \param alMin
|
||||
* \param alMax
|
||||
* \return
|
||||
*/
|
||||
static float RandRectf(float alMin, float alMax);
|
||||
|
||||
/**
|
||||
* Generates a random float from min to max
|
||||
*/
|
||||
static cVector2f RandRectVector2f(const cVector3f &avMin, const cVector3f &avMax);
|
||||
|
||||
/**
|
||||
* Generates a random float from min to max
|
||||
*/
|
||||
static cVector3f RandRectVector3f(const cVector3f &avMin, const cVector3f &avMax);
|
||||
|
||||
/**
|
||||
* Generates a random float from min to max
|
||||
*/
|
||||
static cColor RandRectColor(const cColor &aMin, const cColor &aMax);
|
||||
|
||||
/**
|
||||
* Randomize the rand funcs.
|
||||
* \param alSeed the seed, -1 = random seed.
|
||||
*/
|
||||
static void Randomize(int alSeed = -1);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// COLLSION //////////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
static bool BoxCollision(cRect2l aRect1, cRect2l aRect2);
|
||||
static bool BoxCollision(cRect2f aRect1, cRect2f aRect2);
|
||||
|
||||
static bool PointBoxCollision(cVector2f avPoint, cRect2f aRect);
|
||||
|
||||
static bool BoxFit(cRect2l aRectSrc, cRect2l aRectDest);
|
||||
static bool BoxFit(cRect2f aRectSrc, cRect2f aRectDest);
|
||||
|
||||
static float Dist2D(const cVector2f &avPosA, const cVector2f &avPosB);
|
||||
static float Dist2D(const cVector3f &avPosA, const cVector3f &avPosB);
|
||||
|
||||
static float SqrDist2D(const cVector2f &avPosA, const cVector2f &avPosB);
|
||||
static float SqrDist2D(const cVector3f &avPosA, const cVector3f &avPosB);
|
||||
|
||||
static cRect2f &ClipRect(cRect2f &aRectSrc, const cRect2f &aRectDest);
|
||||
|
||||
/**
|
||||
* Checks collison between two bounding volumes.
|
||||
* \return true if collision, else false.
|
||||
*/
|
||||
static bool CheckCollisionBV(cBoundingVolume &aBV1, cBoundingVolume &aBV2);
|
||||
|
||||
static bool PointBVCollision(const cVector3f &avPoint, cBoundingVolume &aBV2);
|
||||
|
||||
/**
|
||||
* Creates a clip rect for a bounding volume in screen space.
|
||||
* \return false if behind near clip.
|
||||
*/
|
||||
static bool GetClipRectFromBV(cRect2l &aDestRect, cBoundingVolume &aBV,
|
||||
const cMatrixf &a_mtxView, const cMatrixf &a_mtxProj,
|
||||
float afNearClipPlane, const cVector2l &avScreenSize);
|
||||
|
||||
static bool CheckSphereInPlanes(const cVector3f &avCenter, float afRadius,
|
||||
const cPlanef *apPlanes, int alPlaneCount);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// FLOAT OPERATIONS ////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get fraction part of a float
|
||||
* \param afVal
|
||||
* \return
|
||||
*/
|
||||
static float GetFraction(float afVal);
|
||||
/**
|
||||
* Moldus (%) of a float
|
||||
* \param afDividend
|
||||
* \param afDivisor
|
||||
* \return
|
||||
*/
|
||||
static float Modulus(float afDividend, float afDivisor);
|
||||
|
||||
static float ToRad(float afAngle);
|
||||
static float ToDeg(float afAngle);
|
||||
|
||||
/**
|
||||
* Get the Log 2 of an int.
|
||||
*/
|
||||
static int Log2ToInt(int alX);
|
||||
|
||||
/**
|
||||
* Checks if the number is a power of two.
|
||||
*/
|
||||
static bool IsPow2(int alX);
|
||||
|
||||
/**
|
||||
* Wraps a value (afX) between min and max. Example: Wrap(-1, 0,10) returns 9.
|
||||
* \param afMin The minimum value. Must be lower than max.
|
||||
* \param afMax The maximum value. Must be higher than min and NOT 0.
|
||||
*/
|
||||
static float Wrap(float afX, float afMin, float afMax);
|
||||
|
||||
/**
|
||||
* Clamps a value between min and max. Example Clamp(-1, 0,1) return 0.
|
||||
*/
|
||||
static float Clamp(float afX, float afMin, float afMax);
|
||||
|
||||
inline static float Max(float afX, float afY) {
|
||||
if (afX > afY)
|
||||
return afX;
|
||||
return afY;
|
||||
}
|
||||
inline static float Min(float afX, float afY) {
|
||||
if (afX < afY)
|
||||
return afX;
|
||||
return afY;
|
||||
}
|
||||
|
||||
inline static int Max(int alX, int alY) {
|
||||
if (alX > alY)
|
||||
return alX;
|
||||
return alY;
|
||||
}
|
||||
inline static int Min(int alX, int alY) {
|
||||
if (alX < alY)
|
||||
return alX;
|
||||
return alY;
|
||||
}
|
||||
|
||||
inline static float Abs(float afX) { return afX < 0 ? -afX : afX; }
|
||||
inline static int Abs(int alX) { return alX < 0 ? -alX : alX; }
|
||||
|
||||
static float GetAngleDistance(float afAngle1, float afAngle2, float afMaxAngle);
|
||||
static float GetAngleDistanceRad(float afAngle1, float afAngle2);
|
||||
static float GetAngleDistanceDeg(float afAngle1, float afAngle2);
|
||||
|
||||
static float TurnAngle(float afAngle, float afFinalAngle, float afSpeed, float afMaxAngle);
|
||||
static float TurnAngleRad(float afAngle, float afFinalAngle, float afSpeed);
|
||||
static float TurnAngleDeg(float afAngle, float afFinalAngle, float afSpeed);
|
||||
|
||||
static float InterpolateFloat(float afA, float afB, float afT);
|
||||
|
||||
template<typename Vector>
|
||||
static decltype(Vector::x) & GetVectorX(Vector &v) {
|
||||
return v.x;
|
||||
}
|
||||
|
||||
template<typename Vector>
|
||||
static decltype(Vector::y) & GetVectorY(Vector &v) {
|
||||
return v.y;
|
||||
}
|
||||
template<typename Vector>
|
||||
static decltype(Vector::z) & GetVectorZ(Vector &v) {
|
||||
return v.z;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// VECTOR 2D ///////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
/**
|
||||
* Get the angle a vector at aStartPos has to have to look at aGoalPos
|
||||
* \param &aStartPos
|
||||
* \param &avGoalPos
|
||||
* \return
|
||||
*/
|
||||
static float GetAngleFromPoints2D(const cVector2f &aStartPos, const cVector2f &avGoalPos);
|
||||
/**
|
||||
* Get a vector from an angle and a length
|
||||
* \param afAngle
|
||||
* \param afLength
|
||||
* \return
|
||||
*/
|
||||
static cVector2f GetVectorFromAngle2D(float afAngle, float afLength);
|
||||
/**
|
||||
* Get angle and length of a vector
|
||||
* \param &avVec
|
||||
* \param *apAngle
|
||||
* \param *apLength
|
||||
*/
|
||||
static void GetAngleFromVector(const cVector2f &avVec, float *apAngle, float *apLength);
|
||||
|
||||
/**
|
||||
* Project Src on Dest
|
||||
* \param &avSrcVec
|
||||
* \param &avDestVec
|
||||
* \return
|
||||
*/
|
||||
static cVector2f ProjectVector2D(const cVector2f &avSrcVec, const cVector2f &avDestVec);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// VECTOR 3D ///////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
static inline cVector3f Vector3ToRad(const cVector3f &avVec) {
|
||||
return cVector3f(ToRad(avVec.x), ToRad(avVec.y), ToRad(avVec.z));
|
||||
}
|
||||
|
||||
static inline cVector3f Vector3ToDeg(const cVector3f &avVec) {
|
||||
return cVector3f(ToDeg(avVec.x), ToDeg(avVec.y), ToDeg(avVec.z));
|
||||
}
|
||||
|
||||
static inline cVector3f Vector3Normalize(const cVector3f &avVec) {
|
||||
cVector3f vNorm = avVec;
|
||||
vNorm.Normalise();
|
||||
return vNorm;
|
||||
}
|
||||
|
||||
static inline float Vector3DistSqr(const cVector3f &avStartPos, const cVector3f &avEndPos) {
|
||||
float fDX = avEndPos.x - avStartPos.x;
|
||||
float fDY = avEndPos.y - avStartPos.y;
|
||||
float fDZ = avEndPos.z - avStartPos.z;
|
||||
|
||||
return fDX * fDX + fDY * fDY + fDZ * fDZ;
|
||||
}
|
||||
|
||||
static inline float Vector3Dist(const cVector3f &avStartPos, const cVector3f &avEndPos) {
|
||||
return sqrt(Vector3DistSqr(avStartPos, avEndPos));
|
||||
}
|
||||
|
||||
static cVector3f GetAngleFromPoints3D(const cVector3f &avStartPos, const cVector3f &avGoalPos);
|
||||
|
||||
/**
|
||||
* Vector cross product, A x B = R
|
||||
* \param avVecA
|
||||
* \param avVecB
|
||||
* \return
|
||||
*/
|
||||
static cVector3f Vector3Cross(const cVector3f &avVecA, const cVector3f &avVecB);
|
||||
|
||||
/**
|
||||
* Vector dot product, A * B = R
|
||||
* \param avVecA
|
||||
* \param avVecB
|
||||
* \return
|
||||
*/
|
||||
static float Vector3Dot(const cVector3f &avVecA, const cVector3f &avVecB);
|
||||
|
||||
/**
|
||||
* Project Src on Dest
|
||||
* \param &avSrcVec, must be normalized
|
||||
* \param &avDestVec, must be normalized
|
||||
* \return
|
||||
*/
|
||||
static cVector3f ProjectVector3D(const cVector3f &avSrcVec, const cVector3f &avDestVec);
|
||||
|
||||
/**
|
||||
* Calculates the angle between two vectors.
|
||||
* \param avVecA
|
||||
* \param avVecB
|
||||
* \return
|
||||
*/
|
||||
static float Vector3Angle(const cVector3f &avVecA, const cVector3f &avVecB);
|
||||
|
||||
/**
|
||||
* Unprojects a vector from screen size and coords.
|
||||
*/
|
||||
static cVector3f Vector3UnProject(const cVector3f &avVec, const cRect2f &aScreenRect,
|
||||
cMatrixf a_mtxViewProj);
|
||||
|
||||
/**
|
||||
* Calculates distance from a point to a plane
|
||||
* \param aPlane The plane must be normalised!
|
||||
* \param avVec
|
||||
* \return >0 if in front of plane, 0 if on plane and <0 if behind plane
|
||||
*/
|
||||
static float PlaneToPointDist(const cPlanef &aPlane, const cVector3f &avVec);
|
||||
|
||||
/**
|
||||
* Get the line defining the intersection of 2 planes.
|
||||
* \param aPA
|
||||
* \param aPB
|
||||
* \param avDir The direction of the line will be placed here
|
||||
* \param avPoint A point on the line will be placed here.
|
||||
*/
|
||||
static void PlaneIntersectionLine(const cPlanef &aPA, const cPlanef &aPB,
|
||||
cVector3f &avDir, cVector3f &avPoint);
|
||||
|
||||
/**
|
||||
* Checks intersection with a frustum, an array of alPairNum plane pairs(alPairNum*2 planes), and a line,
|
||||
*/
|
||||
static bool CheckFrustumLineIntersection(const cPlanef *apPlanePairs, const cVector3f &avPoint1,
|
||||
const cVector3f &avPoint2, int alPairNum);
|
||||
|
||||
/**
|
||||
* Checks intersection with a a frustum, an array of alPairNum plane pairs(alPairNum * 2 planes), and a quad mesh.
|
||||
* \param apPoints the points of the quad mesh, every 4 points is a face.
|
||||
*/
|
||||
static bool CheckFrustumQuadMeshIntersection(const cPlanef *apPlanePairs, tVector3fVec *apPoints,
|
||||
int alPairNum);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// QUATERNIONS ///////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Spherical Linear Interpolation between quaternions A and B
|
||||
* \param afT The amount in-between the quaternions. 0.0 is A and 1 is B.
|
||||
* \param abShortestPath Move the the shortest path.
|
||||
* \return
|
||||
*/
|
||||
static cQuaternion QuaternionSlerp(float afT, const cQuaternion &aqA, const cQuaternion &aqB,
|
||||
bool abShortestPath);
|
||||
|
||||
static float QuaternionDot(const cQuaternion &aqA, const cQuaternion &aqB);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// MATRIX ////////////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Spherical Linear Interpolation between matrix A and B
|
||||
* \param afT The amount in-between the quaternions. 0.0 is A and 1 is B.
|
||||
* \param abShortestPath Move the the shortest path.
|
||||
* \return
|
||||
*/
|
||||
static cMatrixf MatrixSlerp(float afT, const cMatrixf &a_mtxA, const cMatrixf &a_mtxB,
|
||||
bool abShortestPath);
|
||||
|
||||
/**
|
||||
* Matrix mulitplication, A * B = R. This means that B is applied BEFORE A.
|
||||
*/
|
||||
static cMatrixf MatrixMul(const cMatrixf &a_mtxA, const cMatrixf &a_mtxB);
|
||||
/**
|
||||
* Multiply and matrix and a 3d vector
|
||||
*/
|
||||
static cVector3f MatrixMul(const cMatrixf &a_mtxA, const cVector3f &avB);
|
||||
/**
|
||||
* Multiply and matrix and a 3d vector and divide the result with W.
|
||||
*/
|
||||
static cVector3f MatrixMulDivideW(const cMatrixf &a_mtxA, const cVector3f &avB);
|
||||
|
||||
/**
|
||||
* Multiply matrix and a float.
|
||||
*/
|
||||
static cMatrixf MatrixMulScalar(const cMatrixf &a_mtxA, float afB);
|
||||
|
||||
/**
|
||||
* Creates a rotation matrix along all axes according to order.
|
||||
*/
|
||||
static cMatrixf MatrixRotate(cVector3f avRot, eEulerRotationOrder aOrder);
|
||||
/**
|
||||
* Create a rotation matrix around the X-axis according to the right hand rule
|
||||
*/
|
||||
static cMatrixf MatrixRotateX(float afAngle);
|
||||
/**
|
||||
* Create a rotation matrix around the Y-axis according to the right hand rule
|
||||
*/
|
||||
static cMatrixf MatrixRotateY(float afAngle);
|
||||
/**
|
||||
* Create a rotation matrix around the Z-axis according to the right hand rule
|
||||
*/
|
||||
static cMatrixf MatrixRotateZ(float afAngle);
|
||||
static cMatrixf MatrixScale(cVector3f avScale);
|
||||
static cMatrixf MatrixTranslate(cVector3f avTrans);
|
||||
|
||||
/**
|
||||
* Creates a matrix from a quaternion.
|
||||
* \return
|
||||
*/
|
||||
static cMatrixf MatrixQuaternion(const cQuaternion &aqRot);
|
||||
|
||||
/**
|
||||
* Get the minor of a matrix.
|
||||
*/
|
||||
static inline float MatrixMinor(const cMatrixf &a_mtxA,
|
||||
const size_t r0, const size_t r1, const size_t r2,
|
||||
const size_t c0, const size_t c1, const size_t c2);
|
||||
/**
|
||||
* Get the adjoint of a matrix.
|
||||
*/
|
||||
static inline cMatrixf MatrixAdjoint(const cMatrixf &a_mtxA);
|
||||
|
||||
/**
|
||||
* Get the determinant of a matrix.
|
||||
*/
|
||||
static inline float MatrixDeterminant(const cMatrixf &a_mtxA);
|
||||
|
||||
/**
|
||||
* Gets the inverse of a matrix.
|
||||
*/
|
||||
static cMatrixf MatrixInverse(const cMatrixf &a_mtxA);
|
||||
|
||||
/**
|
||||
* Converts the matrix into Euler angles, XYZ only supported at the moment.
|
||||
* \param &a_mtxA
|
||||
* \param aOrder
|
||||
*/
|
||||
static cVector3f MatrixToEulerAngles(const cMatrixf &a_mtxA, eEulerRotationOrder aOrder);
|
||||
|
||||
/**
|
||||
* Create a char string from the matrix
|
||||
*/
|
||||
static const char *MatrixToChar(const cMatrixf &a_mtxA);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////// POLYGONS //////////////////////////////////
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Creates an array with 4d tangent vectors for triangles. alIndexNum % 3 must be 0.
|
||||
* \param apDestArray The destination array, must be 4 * number of vertices large
|
||||
* \param apIndexArray The indices
|
||||
* \param alIndexNum Number of indices
|
||||
* \param apVertexArray Vertices indexed by the indices
|
||||
* \param apTexArray The texture coords
|
||||
* \param apNormalArray The normals
|
||||
* \param alVertexNum Number of vertex, normals and texcoords.
|
||||
* \return true if success, else false
|
||||
*/
|
||||
static bool CreateTriTangentVectors(float *apDestArray,
|
||||
const unsigned int *apIndexArray, int alIndexNum,
|
||||
const float *apVertexArray, int alVtxStride,
|
||||
const float *apTexArray,
|
||||
const float *apNormalArray, int alVertexNum);
|
||||
|
||||
/**
|
||||
* Creates triangle data for a triangle mesh. alIndexNum % 3 must be 0.
|
||||
* \param avTriangles Where the data will be stored. If empty, this function resizes it.
|
||||
* \param apIndexArray The indices
|
||||
* \param alIndexNum Number of indices
|
||||
* \param apVertexArray Vertices indexed by the indices
|
||||
* \param alVertexNum Number of vertices
|
||||
* \return true if success, else false
|
||||
*/
|
||||
static bool CreateTriangleData(tTriangleDataVec &avTriangles,
|
||||
const unsigned int *apIndexArray, int alIndexNum,
|
||||
const float *apVertexArray, int alVtxStride, int alVertexNum);
|
||||
|
||||
/**
|
||||
* Creates edges for a triangle mesh. alIndexNum % 3 must be 0.
|
||||
* \param avEdges An empty edge vector, this is where the edges will be stored.
|
||||
* \param apIndexArray The indices
|
||||
* \param alIndexNum Number of indices
|
||||
* \param apVertexArray Vertices indexed by the indices
|
||||
* \param alVertexNum Number of vertices
|
||||
* \return true if success, else false
|
||||
*/
|
||||
static bool CreateEdges(tTriEdgeVec &avEdges,
|
||||
const unsigned int *apIndexArray, int alIndexNum,
|
||||
const float *apVertexArray, int alVtxStride, int alVertexNum,
|
||||
bool *apIsDoubleSided);
|
||||
};
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_MATH_H
|
||||
41
engines/hpl1/engine/math/MathTypes.cpp
Normal file
41
engines/hpl1/engine/math/MathTypes.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
|
||||
namespace hpl {
|
||||
template<>
|
||||
const cMatrixf cMatrixf::Identity(1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
template<>
|
||||
const cMatrixf cMatrixf::Zero(0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
} // namespace hpl
|
||||
299
engines/hpl1/engine/math/MathTypes.h
Normal file
299
engines/hpl1/engine/math/MathTypes.h
Normal file
@@ -0,0 +1,299 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_MATHTYPES_H
|
||||
#define HPL_MATHTYPES_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/list.h"
|
||||
#include "hpl1/engine/math/Vector2.h"
|
||||
#include "hpl1/engine/math/Vector3.h"
|
||||
#include "hpl1/engine/math/hplMatrix.h"
|
||||
#include "hpl1/engine/system/SystemTypes.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
#define kPif (3.141592654f)
|
||||
#define kPi2f (1.570796327f)
|
||||
#define kPi4f (0.7853981634f)
|
||||
#define k2Pif (6.283185307f)
|
||||
|
||||
#define kEpsilonf (0.0001f)
|
||||
|
||||
#define kSqrt2f (1.414213562f)
|
||||
|
||||
enum eEulerRotationOrder {
|
||||
eEulerRotationOrder_XYZ,
|
||||
eEulerRotationOrder_XZY,
|
||||
eEulerRotationOrder_YXZ,
|
||||
eEulerRotationOrder_YZX,
|
||||
eEulerRotationOrder_ZXY,
|
||||
eEulerRotationOrder_ZYX,
|
||||
eEulerRotationOrder_LastEnum,
|
||||
};
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
class cLinearOscillation {
|
||||
public:
|
||||
float max, min, val, up_speed, down_speed;
|
||||
|
||||
cLinearOscillation() {}
|
||||
cLinearOscillation(float afMin, float afMax, float afVal, float afUpSpeed, float afDownSpeed) {
|
||||
SetUp(afMin, afMax, afVal, afUpSpeed, afDownSpeed);
|
||||
}
|
||||
|
||||
void SetUp(float afMin, float afMax, float afVal, float afUpSpeed, float afDownSpeed) {
|
||||
min = afMin;
|
||||
max = afMax;
|
||||
val = afVal;
|
||||
|
||||
up_speed = ABS(afUpSpeed);
|
||||
down_speed = -ABS(afDownSpeed);
|
||||
|
||||
add = up_speed;
|
||||
}
|
||||
|
||||
void Update(float afTimeStep) {
|
||||
val += add * afTimeStep;
|
||||
if (add > 0) {
|
||||
if (val >= max) {
|
||||
val = max;
|
||||
add = down_speed;
|
||||
}
|
||||
} else {
|
||||
if (val <= min) {
|
||||
val = min;
|
||||
add = up_speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
float add;
|
||||
};
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
template<class T>
|
||||
class cPlane {
|
||||
public:
|
||||
T a, b, c, d;
|
||||
cVector3<T> normal;
|
||||
|
||||
/////////////////
|
||||
|
||||
cPlane(T aA, T aB, T aC, T aD) {
|
||||
a = aA;
|
||||
b = aB;
|
||||
c = aC;
|
||||
d = aD;
|
||||
}
|
||||
|
||||
cPlane() {
|
||||
a = 0;
|
||||
b = 0;
|
||||
c = 0;
|
||||
d = 0;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
||||
cPlane(const cVector3<T> &avNormal, const cVector3<T> &avPoint) {
|
||||
FromNormalPoint(avNormal, avPoint);
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
||||
cPlane(const cVector3<T> &avPoint0, const cVector3<T> &avPoint1,
|
||||
const cVector3<T> &avPoint2) {
|
||||
FromPoints(avPoint0, avPoint1, avPoint2);
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
||||
inline void FromNormalPoint(const cVector3<T> &avNormal, const cVector3<T> &avPoint) {
|
||||
a = avNormal.x;
|
||||
b = avNormal.y;
|
||||
c = avNormal.z;
|
||||
|
||||
// Dot product
|
||||
d = -(avNormal.x * avPoint.x + avNormal.y * avPoint.y + avNormal.z * avPoint.z);
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
||||
inline void FromPoints(const cVector3<T> &avPoint0, const cVector3<T> &avPoint1,
|
||||
const cVector3<T> &avPoint2) {
|
||||
cVector3<T> vEdge1 = avPoint1 - avPoint0;
|
||||
cVector3<T> vEdge2 = avPoint2 - avPoint0;
|
||||
|
||||
// Cross product
|
||||
normal.x = vEdge1.y * vEdge2.z - vEdge1.z * vEdge2.y;
|
||||
normal.y = vEdge1.z * vEdge2.x - vEdge1.x * vEdge2.z;
|
||||
normal.z = vEdge1.x * vEdge2.y - vEdge1.y * vEdge2.x;
|
||||
|
||||
normal.Normalise();
|
||||
|
||||
a = normal.x;
|
||||
b = normal.y;
|
||||
c = normal.z;
|
||||
|
||||
// Dot product
|
||||
d = -(normal.x * avPoint0.x + normal.y * avPoint0.y + normal.z * avPoint0.z);
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
||||
inline void Normalise() {
|
||||
T fMag = sqrt(a * a + b * b + c * c);
|
||||
a = a / fMag;
|
||||
b = b / fMag;
|
||||
c = c / fMag;
|
||||
d = d / fMag;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
||||
inline void CalcNormal() {
|
||||
normal = cVector3<T>(a, b, c);
|
||||
normal.Normalise();
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
||||
void FromVec(T *apV) {
|
||||
a = apV[0];
|
||||
b = apV[1];
|
||||
c = apV[2];
|
||||
d = apV[3];
|
||||
|
||||
CalcNormal();
|
||||
}
|
||||
};
|
||||
|
||||
typedef cPlane<float> cPlanef;
|
||||
typedef Common::Array<cPlanef> tPlanefVec;
|
||||
typedef tPlanefVec tPlanefVecIt;
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
template<class T>
|
||||
class cSphere {
|
||||
public:
|
||||
T r;
|
||||
cVector3<T> center;
|
||||
|
||||
cSphere() {
|
||||
}
|
||||
|
||||
cSphere(cVector3<T> aV, T aR) {
|
||||
center = aV;
|
||||
r = aR;
|
||||
}
|
||||
};
|
||||
|
||||
typedef cSphere<float> cSpheref;
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
template<class T>
|
||||
class cRect2 {
|
||||
public:
|
||||
T x, y, w, h;
|
||||
cRect2(T aX, T aY, T aW, T aH) {
|
||||
x = aX;
|
||||
y = aY;
|
||||
w = aW;
|
||||
h = aH;
|
||||
}
|
||||
cRect2(T aX, T aY) {
|
||||
x = aX;
|
||||
y = aY;
|
||||
w = 0;
|
||||
h = 0;
|
||||
}
|
||||
cRect2() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = 0;
|
||||
h = 0;
|
||||
}
|
||||
cRect2(cVector2<T> aPos, cVector2<T> aSize) {
|
||||
x = aPos.x;
|
||||
y = aPos.y;
|
||||
w = aSize.x;
|
||||
h = aSize.y;
|
||||
}
|
||||
|
||||
void FromVec(T *apV) {
|
||||
x = apV[0];
|
||||
y = apV[1];
|
||||
w = apV[2];
|
||||
h = apV[3];
|
||||
}
|
||||
};
|
||||
|
||||
typedef cRect2<float> cRect2f;
|
||||
typedef cRect2<int> cRect2l;
|
||||
typedef Common::List<cRect2f> tRect2lList;
|
||||
typedef tRect2lList tRect2lListIt;
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
typedef cVector2<float> cVector2f;
|
||||
typedef cVector2<int> cVector2l;
|
||||
|
||||
typedef cMatrix<float> cMatrixf;
|
||||
|
||||
typedef Common::Array<cMatrixf> tMatrixfVec;
|
||||
typedef tMatrixfVec::iterator tMatrixfVecIt;
|
||||
|
||||
typedef Common::List<cMatrixf> tMatrixfList;
|
||||
typedef tMatrixfList::iterator tMatrixfListIt;
|
||||
|
||||
typedef Common::List<cVector2f> tVector2fList;
|
||||
typedef tVector2fList::iterator tVector2fListIt;
|
||||
|
||||
typedef cVector3<float> cVector3f;
|
||||
typedef cVector3<int> cVector3l;
|
||||
|
||||
typedef Common::List<cVector3f> tVector3fList;
|
||||
typedef tVector3fList::iterator tVector3fListIt;
|
||||
|
||||
typedef Common::Array<cVector2f> tVector2fVec;
|
||||
typedef tVector2fVec::iterator tVector2fVecIt;
|
||||
|
||||
typedef Common::Array<cVector3f> tVector3fVec;
|
||||
typedef tVector3fList::iterator tVector3fVecIt;
|
||||
|
||||
//-------------------------------------------
|
||||
} // namespace hpl
|
||||
|
||||
#include "hpl1/engine/math/Quaternion.h"
|
||||
|
||||
#endif // HPL_MATHTYPES_H
|
||||
26
engines/hpl1/engine/math/MeshTypes.cpp
Normal file
26
engines/hpl1/engine/math/MeshTypes.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
74
engines/hpl1/engine/math/MeshTypes.h
Normal file
74
engines/hpl1/engine/math/MeshTypes.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_MESH_TYPES_H
|
||||
#define HPL_MESH_TYPES_H
|
||||
|
||||
#include "hpl1/engine/math/BoundingVolume.h"
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//----------------------------------------------
|
||||
|
||||
class cTriangleData {
|
||||
public:
|
||||
cVector3f normal;
|
||||
bool facingLight;
|
||||
|
||||
cTriangleData() {}
|
||||
cTriangleData(const cVector3f &avNormal) {
|
||||
normal = avNormal;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Common::Array<cTriangleData> tTriangleDataVec;
|
||||
typedef tTriangleDataVec::iterator tTriangleDataVecIt;
|
||||
|
||||
//----------------------------------------------
|
||||
|
||||
class cTriEdge {
|
||||
public:
|
||||
int point1 = 0;
|
||||
int point2 = 0;
|
||||
mutable int tri1 = 0;
|
||||
mutable int tri2 = 0;
|
||||
bool invert_tri2 = false;
|
||||
|
||||
cTriEdge() = default;
|
||||
constexpr cTriEdge(int alPoint1, int alPoint2, int alTri1, int alTri2) : point1(alPoint1), point2(alPoint2), tri1(alTri1), tri2(alTri2), invert_tri2(false) {
|
||||
}
|
||||
};
|
||||
|
||||
typedef Common::Array<cTriEdge> tTriEdgeVec;
|
||||
typedef tTriEdgeVec::iterator tTriEdgeVecIt;
|
||||
|
||||
//----------------------------------------------
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_MESH_TYPES_H
|
||||
135
engines/hpl1/engine/math/PidController.h
Normal file
135
engines/hpl1/engine/math/PidController.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_PID_CONTROLLER_H
|
||||
#define HPL_PID_CONTROLLER_H
|
||||
|
||||
#include "hpl1/algorithms.h"
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
template<class T>
|
||||
class cPidController {
|
||||
public:
|
||||
float p, i, d;
|
||||
//////////////////////////////////////////
|
||||
// Constructors
|
||||
/////////////////////////////////////////
|
||||
cPidController() {
|
||||
Reset();
|
||||
}
|
||||
cPidController(float afP, float afI, float afD, int alErrorNum) {
|
||||
p = afP;
|
||||
i = afI;
|
||||
d = afD;
|
||||
SetErrorNum(alErrorNum);
|
||||
Reset();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Public
|
||||
/////////////////////////////////////////
|
||||
|
||||
//------------------------------------
|
||||
T Output(T aError, float afTimeStep) {
|
||||
mvErrors[mlErrorNum] = aError;
|
||||
mvTimeSteps[mlErrorNum] = afTimeStep;
|
||||
|
||||
integral = 0;
|
||||
size_t lCount = mvErrors.size();
|
||||
for (size_t error = 0; error < lCount; ++error) {
|
||||
integral += mvErrors[error] * mvTimeSteps[error];
|
||||
}
|
||||
|
||||
derivative = 0.0f;
|
||||
if (mlLastNum >= 0) {
|
||||
derivative = (mvErrors[mlErrorNum] - mvErrors[mlLastNum]) / afTimeStep;
|
||||
}
|
||||
|
||||
mlLastNum = mlErrorNum;
|
||||
mlErrorNum++;
|
||||
if (mlErrorNum >= (int)mvErrors.size())
|
||||
mlErrorNum = 0;
|
||||
|
||||
return mvErrors[mlLastNum] * p + integral * i + derivative * d;
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
void SetErrorNum(int alErrorNum) {
|
||||
mvErrors.resize(alErrorNum);
|
||||
Hpl1::resizeAndFill(mvTimeSteps, alErrorNum, 0.f);
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
void Reset() {
|
||||
mlErrorNum = 0;
|
||||
mlLastNum = -1;
|
||||
Common::fill(mvTimeSteps.begin(), mvTimeSteps.end(), 0);
|
||||
|
||||
integral = 0;
|
||||
derivative = 0;
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
T GetLastError() {
|
||||
if (mlLastNum >= 0)
|
||||
return mvErrors[mlLastNum];
|
||||
return 0;
|
||||
}
|
||||
|
||||
T GetLastDerivative() {
|
||||
return derivative;
|
||||
}
|
||||
|
||||
T GetLastIntegral() {
|
||||
return integral;
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
private:
|
||||
Common::Array<T> mvErrors;
|
||||
Common::Array<float> mvTimeSteps;
|
||||
|
||||
T integral, derivative;
|
||||
|
||||
int mlErrorNum;
|
||||
int mlLastNum;
|
||||
};
|
||||
|
||||
//---------------------------------
|
||||
|
||||
typedef cPidController<float> cPidControllerf;
|
||||
typedef cPidController<cVector3f> cPidControllerVec3;
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_PID_CONTROLLER_H
|
||||
186
engines/hpl1/engine/math/Quaternion.cpp
Normal file
186
engines/hpl1/engine/math/Quaternion.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/math/Quaternion.h"
|
||||
|
||||
#include "hpl1/engine/math/Math.h"
|
||||
#include "hpl1/engine/system/low_level_system.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cQuaternion::cQuaternion() {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cQuaternion::cQuaternion(float afAngle, const cVector3f &avAxis) {
|
||||
FromAngleAxis(afAngle, avAxis);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const cQuaternion cQuaternion::Identity = cQuaternion(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cQuaternion::Normalise() {
|
||||
float fLen = w * w + v.x * v.x + v.y * v.y + v.z * v.z;
|
||||
float fFactor = 1.0f / sqrt(fLen);
|
||||
v = v * fFactor;
|
||||
w = w * fFactor;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cQuaternion::ToRotationMatrix(cMatrixf &a_mtxDest) const {
|
||||
cMatrixf mtxA;
|
||||
|
||||
float fTx = 2.0f * v.x;
|
||||
float fTy = 2.0f * v.y;
|
||||
float fTz = 2.0f * v.z;
|
||||
float fTwx = fTx * w;
|
||||
float fTwy = fTy * w;
|
||||
float fTwz = fTz * w;
|
||||
float fTxx = fTx * v.x;
|
||||
float fTxy = fTy * v.x;
|
||||
float fTxz = fTz * v.x;
|
||||
float fTyy = fTy * v.y;
|
||||
float fTyz = fTz * v.y;
|
||||
float fTzz = fTz * v.z;
|
||||
|
||||
a_mtxDest.m[0][0] = 1.0f - (fTyy + fTzz);
|
||||
a_mtxDest.m[0][1] = fTxy - fTwz;
|
||||
a_mtxDest.m[0][2] = fTxz + fTwy;
|
||||
a_mtxDest.m[1][0] = fTxy + fTwz;
|
||||
a_mtxDest.m[1][1] = 1.0f - (fTxx + fTzz);
|
||||
a_mtxDest.m[1][2] = fTyz - fTwx;
|
||||
a_mtxDest.m[2][0] = fTxz - fTwy;
|
||||
a_mtxDest.m[2][1] = fTyz + fTwx;
|
||||
a_mtxDest.m[2][2] = 1.0f - (fTxx + fTyy);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cQuaternion::FromRotationMatrix(const cMatrix<float> &a_mtxRot) {
|
||||
float fTrace = a_mtxRot.m[0][0] + a_mtxRot.m[1][1] + a_mtxRot.m[2][2];
|
||||
float fRoot;
|
||||
|
||||
if (fTrace > 0.0) {
|
||||
// |w| > 1/2, may as well choose w > 1/2
|
||||
fRoot = sqrt(fTrace + 1.0f); // 2w
|
||||
w = 0.5f * fRoot;
|
||||
fRoot = 0.5f / fRoot; // 1/(4w)
|
||||
v.x = (a_mtxRot.m[2][1] - a_mtxRot.m[1][2]) * fRoot;
|
||||
v.y = (a_mtxRot.m[0][2] - a_mtxRot.m[2][0]) * fRoot;
|
||||
v.z = (a_mtxRot.m[1][0] - a_mtxRot.m[0][1]) * fRoot;
|
||||
} else {
|
||||
// |w| <= 1/2
|
||||
static size_t s_iNext[3] = {1, 2, 0};
|
||||
size_t i = 0;
|
||||
if (a_mtxRot.m[1][1] > a_mtxRot.m[0][0])
|
||||
i = 1;
|
||||
if (a_mtxRot.m[2][2] > a_mtxRot.m[i][i])
|
||||
i = 2;
|
||||
size_t j = s_iNext[i];
|
||||
size_t k = s_iNext[j];
|
||||
|
||||
fRoot = sqrt(a_mtxRot.m[i][i] - a_mtxRot.m[j][j] - a_mtxRot.m[k][k] + 1.0f);
|
||||
float *apkQuat[3] = {&v.x, &v.y, &v.z};
|
||||
*apkQuat[i] = 0.5f * fRoot;
|
||||
fRoot = 0.5f / fRoot;
|
||||
w = (a_mtxRot.m[k][j] - a_mtxRot.m[j][k]) * fRoot;
|
||||
*apkQuat[j] = (a_mtxRot.m[j][i] + a_mtxRot.m[i][j]) * fRoot;
|
||||
*apkQuat[k] = (a_mtxRot.m[k][i] + a_mtxRot.m[i][k]) * fRoot;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cQuaternion::FromAngleAxis(float afAngle, const cVector3f &avAxis) {
|
||||
// assert: axis[] is unit length
|
||||
//
|
||||
// The quaternion representing the rotation is
|
||||
// q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)
|
||||
|
||||
float fHalfAngle = 0.5f * afAngle;
|
||||
float fSin = sin(fHalfAngle);
|
||||
w = cos(fHalfAngle);
|
||||
v.x = fSin * avAxis.x;
|
||||
v.y = fSin * avAxis.y;
|
||||
v.z = fSin * avAxis.z;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cQuaternion cQuaternion::operator+(const cQuaternion &aqB) const {
|
||||
cQuaternion qOut;
|
||||
qOut.v = v + aqB.v;
|
||||
qOut.w = w + aqB.w;
|
||||
|
||||
return qOut;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cQuaternion cQuaternion::operator-(const cQuaternion &aqB) const {
|
||||
cQuaternion qOut;
|
||||
qOut.v = v - aqB.v;
|
||||
qOut.w = w - aqB.w;
|
||||
|
||||
return qOut;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
cQuaternion cQuaternion::operator*(const cQuaternion &aqB) const {
|
||||
cQuaternion qOut;
|
||||
|
||||
qOut.w = w * aqB.w - v.x * aqB.v.x - v.y * aqB.v.y - v.z * aqB.v.z;
|
||||
qOut.v.x = w * aqB.v.x + v.x * aqB.w + v.y * aqB.v.z - v.z * aqB.v.y;
|
||||
qOut.v.y = w * aqB.v.y + v.y * aqB.w + v.z * aqB.v.x - v.x * aqB.v.z;
|
||||
qOut.v.z = w * aqB.v.z + v.z * aqB.w + v.x * aqB.v.y - v.y * aqB.v.x;
|
||||
|
||||
return qOut;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
cQuaternion cQuaternion::operator*(float afScalar) const {
|
||||
cQuaternion qOut;
|
||||
qOut.v = v * afScalar;
|
||||
qOut.w = w * afScalar;
|
||||
|
||||
return qOut;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
} // namespace hpl
|
||||
69
engines/hpl1/engine/math/Quaternion.h
Normal file
69
engines/hpl1/engine/math/Quaternion.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_QUATERNION_H
|
||||
#define HPL_QUATERNION_H
|
||||
|
||||
#include "hpl1/engine/math/Vector3.h"
|
||||
#include "hpl1/engine/math/hplMatrix.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
class cQuaternion {
|
||||
public:
|
||||
cVector3<float> v;
|
||||
float w;
|
||||
|
||||
cQuaternion();
|
||||
cQuaternion(float afAngle, const cVector3<float> &avAxis);
|
||||
constexpr cQuaternion(float afW, float afX, float afY, float afZ) : v(afX, afY, afZ), w(afW) {
|
||||
}
|
||||
|
||||
void Normalise();
|
||||
void ToRotationMatrix(cMatrix<float> &a_mtxDest) const;
|
||||
void FromRotationMatrix(const cMatrix<float> &a_mtxRot);
|
||||
|
||||
/**
|
||||
* Set the quaternion from and angle and axis.
|
||||
* \param afAngle
|
||||
* \param &avAxis MUST be unit length!
|
||||
*/
|
||||
void FromAngleAxis(float afAngle, const cVector3<float> &avAxis);
|
||||
|
||||
cQuaternion operator+(const cQuaternion &aqB) const;
|
||||
cQuaternion operator-(const cQuaternion &aqB) const;
|
||||
cQuaternion operator*(const cQuaternion &aqB) const;
|
||||
cQuaternion operator*(float afScalar) const;
|
||||
|
||||
static const cQuaternion Identity;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_QUATERNION_H
|
||||
28
engines/hpl1/engine/math/Spring.cpp
Normal file
28
engines/hpl1/engine/math/Spring.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/math/Spring.h"
|
||||
67
engines/hpl1/engine/math/Spring.h
Normal file
67
engines/hpl1/engine/math/Spring.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_SPRING_H
|
||||
#define HPL_SPRING_H
|
||||
|
||||
#include "hpl1/engine/math/MathTypes.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
template<class T>
|
||||
class cSpring {
|
||||
public:
|
||||
float k;
|
||||
float b;
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Constructors
|
||||
/////////////////////////////////////////
|
||||
cSpring() {}
|
||||
|
||||
cSpring(float afK, float afB) {
|
||||
k = afK;
|
||||
b = afB;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Public
|
||||
/////////////////////////////////////////
|
||||
|
||||
T Output(T aError, T aV) {
|
||||
return aError * k - aV * b;
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------
|
||||
|
||||
typedef cSpring<float> cSpringf;
|
||||
typedef cSpring<cVector3f> cSpringVec3;
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_SPRING_H
|
||||
231
engines/hpl1/engine/math/Vector2.h
Normal file
231
engines/hpl1/engine/math/Vector2.h
Normal file
@@ -0,0 +1,231 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_VECTOR2_H
|
||||
#define HPL_VECTOR2_H
|
||||
|
||||
#include "hpl1/engine/system/SystemTypes.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
template<class T>
|
||||
class cVector2 {
|
||||
public:
|
||||
T x, y;
|
||||
#if 0
|
||||
union{
|
||||
struct {
|
||||
T x,y;
|
||||
};
|
||||
T v[2];
|
||||
};
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Constructors
|
||||
/////////////////////////////////////////
|
||||
constexpr cVector2() : x(0), y(0) {
|
||||
}
|
||||
|
||||
constexpr cVector2(T aVal) : x(aVal), y(aVal) {
|
||||
}
|
||||
|
||||
constexpr cVector2(T aX, T aY) : x(aX), y(aY) {
|
||||
}
|
||||
|
||||
constexpr cVector2(cVector2<T> const &aVec) : x(aVec.x), y(aVec.y) {
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Copy
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline cVector2<T> &operator=(const cVector2<T> &aVec) {
|
||||
x = aVec.x;
|
||||
y = aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector2<T> &operator=(const T aVal) {
|
||||
x = aVal;
|
||||
y = aVal;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Boolean
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline bool operator==(const cVector2<T> &aVec) const {
|
||||
if (x == aVec.x && y == aVec.y)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator!=(const cVector2<T> &aVec) const {
|
||||
if (x == aVec.x && y == aVec.y)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Vector Arithmetic
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline cVector2<T> operator+(const cVector2<T> &aVec) const {
|
||||
cVector2<T> vec;
|
||||
vec.x = x + aVec.x;
|
||||
vec.y = y + aVec.y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector2<T> operator-(const cVector2<T> &aVec) const {
|
||||
cVector2<T> vec;
|
||||
vec.x = x - aVec.x;
|
||||
vec.y = y - aVec.y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector2<T> operator*(const cVector2<T> &aVec) const {
|
||||
cVector2<T> vec;
|
||||
vec.x = x * aVec.x;
|
||||
vec.y = y * aVec.y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector2<T> operator/(const cVector2<T> &aVec) const {
|
||||
cVector2<T> vec;
|
||||
vec.x = x / aVec.x;
|
||||
vec.y = y / aVec.y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector2<T> &operator-=(const cVector2<T> &aVec) {
|
||||
x -= aVec.x;
|
||||
y -= aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector2<T> &operator+=(const cVector2<T> &aVec) {
|
||||
x += aVec.x;
|
||||
y += aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector2<T> &operator*=(const cVector2<T> &aVec) {
|
||||
x *= aVec.x;
|
||||
y *= aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector2<T> &operator/=(const cVector2<T> &aVec) {
|
||||
x /= aVec.x;
|
||||
y /= aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Real Arithmetic
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline cVector2<T> operator/(const T &aVal) const {
|
||||
cVector2<T> vec;
|
||||
vec.x = x / aVal;
|
||||
vec.y = y / aVal;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector2<T> operator*(const T &aVal) const {
|
||||
cVector2<T> vec;
|
||||
vec.x = x * aVal;
|
||||
vec.y = y * aVal;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector2<T> operator+(const T &aVal) const {
|
||||
cVector2<T> vec;
|
||||
vec.x = x + aVal;
|
||||
vec.y = y + aVal;
|
||||
return vec;
|
||||
}
|
||||
|
||||
cVector2<T> operator-(const T &aVal) const {
|
||||
cVector2<T> vec;
|
||||
vec.x = x - aVal;
|
||||
vec.y = y - aVal;
|
||||
return vec;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Methods
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline void FromVec(const T *apVec) {
|
||||
x = apVec[0];
|
||||
y = apVec[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use this on double or float vectors
|
||||
* \return Length of Vector
|
||||
*/
|
||||
T Normalise() {
|
||||
T length = sqrt(x * x + y * y);
|
||||
|
||||
if (length > 1e-08) {
|
||||
T InvLength = 1.0f / length;
|
||||
x *= InvLength;
|
||||
y *= InvLength;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Printing
|
||||
/////////////////////////////////////////
|
||||
|
||||
tString ToString() const {
|
||||
char buf[512];
|
||||
snprintf(buf, 512, "%f : %f", x, y);
|
||||
tString str = buf;
|
||||
return str;
|
||||
}
|
||||
|
||||
tString ToFileString() const {
|
||||
char buf[512];
|
||||
snprintf(buf, 512, "%g %g", x, y);
|
||||
tString str = buf;
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_VECTOR2_H
|
||||
334
engines/hpl1/engine/math/Vector3.h
Normal file
334
engines/hpl1/engine/math/Vector3.h
Normal file
@@ -0,0 +1,334 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_VECTOR3_H
|
||||
#define HPL_VECTOR3_H
|
||||
|
||||
#include "hpl1/engine/math/Vector2.h"
|
||||
|
||||
#define VEC3_CONST_ARRAY(name, vec) const float name[] = {vec.x, vec.y, vec.z}
|
||||
|
||||
namespace hpl {
|
||||
|
||||
template<class T>
|
||||
class cVector3 {
|
||||
public:
|
||||
T x, y, z;
|
||||
|
||||
constexpr cVector3() : x(0), y(0), z(0) {
|
||||
}
|
||||
constexpr cVector3(T aVal) : x(aVal), y(aVal), z(aVal) {
|
||||
}
|
||||
constexpr cVector3(T aX, T aY, T aZ) : x(aX), y(aY), z(aZ) {
|
||||
}
|
||||
|
||||
constexpr cVector3(cVector3<T> const &aVec) : x(aVec.x), y(aVec.y), z(aVec.z) {
|
||||
}
|
||||
|
||||
constexpr cVector3(cVector2<T> const &aVec) : x(aVec.x), y(aVec.y), z(0) {
|
||||
}
|
||||
|
||||
static cVector3 fromArray(const float vec[3]) {
|
||||
return cVector3<T>(vec[0], vec[1], vec[2]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Copy
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline cVector3<T> &operator=(const cVector3<T> &aVec) {
|
||||
x = aVec.x;
|
||||
y = aVec.y;
|
||||
z = aVec.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator=(const cVector2<T> &aVec) {
|
||||
x = aVec.x;
|
||||
y = aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator=(const T aVal) {
|
||||
x = aVal;
|
||||
y = aVal;
|
||||
z = aVal;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Boolean
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline bool operator==(const cVector3<T> &aVec) const {
|
||||
if (x == aVec.x && y == aVec.y && z == aVec.z)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator!=(const cVector3<T> &aVec) const {
|
||||
if (x == aVec.x && y == aVec.y && z == aVec.z)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator<(const cVector3<T> &aVec) const {
|
||||
if (x != aVec.x)
|
||||
return x < aVec.x;
|
||||
if (y != aVec.y)
|
||||
return y < aVec.y;
|
||||
return z < aVec.z;
|
||||
}
|
||||
|
||||
inline bool operator>(const cVector3<T> &aVec) const {
|
||||
if (x != aVec.x)
|
||||
return x > aVec.x;
|
||||
if (y != aVec.y)
|
||||
return y > aVec.y;
|
||||
return z > aVec.z;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Vector3 Arithmetic
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline cVector3<T> operator+(const cVector3<T> &aVec) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x + aVec.x;
|
||||
vec.y = y + aVec.y;
|
||||
vec.z = z + aVec.z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> operator-(const cVector3<T> &aVec) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x - aVec.x;
|
||||
vec.y = y - aVec.y;
|
||||
vec.z = z - aVec.z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> operator*(const cVector3<T> &aVec) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x * aVec.x;
|
||||
vec.y = y * aVec.y;
|
||||
vec.z = z * aVec.z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> operator/(const cVector3<T> &aVec) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x / aVec.x;
|
||||
vec.y = y / aVec.y;
|
||||
vec.z = z / aVec.z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator-=(const cVector3<T> &aVec) {
|
||||
x -= aVec.x;
|
||||
y -= aVec.y;
|
||||
z -= aVec.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator+=(const cVector3<T> &aVec) {
|
||||
x += aVec.x;
|
||||
y += aVec.y;
|
||||
z += aVec.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator*=(const cVector3<T> &aVec) {
|
||||
x *= aVec.x;
|
||||
y *= aVec.y;
|
||||
z *= aVec.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator/=(const cVector3<T> &aVec) {
|
||||
x /= aVec.x;
|
||||
y /= aVec.y;
|
||||
z /= aVec.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Vector2 Arithmetic
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline cVector3<T> operator+(const cVector2<T> &aVec) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x + aVec.x;
|
||||
vec.y = y + aVec.y;
|
||||
vec.z = z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> operator-(const cVector2<T> &aVec) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x - aVec.x;
|
||||
vec.y = y - aVec.y;
|
||||
vec.z = z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> operator*(const cVector2<T> &aVec) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x * aVec.x;
|
||||
vec.y = y * aVec.y;
|
||||
vec.z = z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> operator/(const cVector2<T> &aVec) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x / aVec.x;
|
||||
vec.y = y / aVec.y;
|
||||
vec.z = z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator-=(const cVector2<T> &aVec) {
|
||||
x -= aVec.x;
|
||||
y -= aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator+=(const cVector2<T> &aVec) {
|
||||
x += aVec.x;
|
||||
y += aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator*=(const cVector2<T> &aVec) {
|
||||
x *= aVec.x;
|
||||
y *= aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline cVector3<T> &operator/=(const cVector2<T> &aVec) {
|
||||
x /= aVec.x;
|
||||
y /= aVec.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Single Float Arithmetic
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline cVector3<T> operator/(const T &aVal) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x / aVal;
|
||||
vec.y = y / aVal;
|
||||
vec.z = z / aVal;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> operator*(const T &aVal) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x * aVal;
|
||||
vec.y = y * aVal;
|
||||
vec.z = z * aVal;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline cVector3<T> operator+(const T &aVal) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x + aVal;
|
||||
vec.y = y + aVal;
|
||||
vec.z = z + aVal;
|
||||
return vec;
|
||||
}
|
||||
|
||||
cVector3<T> operator-(const T &aVal) const {
|
||||
cVector3<T> vec;
|
||||
vec.x = x - aVal;
|
||||
vec.y = y - aVal;
|
||||
vec.z = z - aVal;
|
||||
return vec;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Methods
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline void FromVec(const T *apVec) {
|
||||
x = apVec[0];
|
||||
y = apVec[1];
|
||||
z = apVec[2];
|
||||
}
|
||||
|
||||
inline T Length() {
|
||||
return sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
inline T SqrLength() {
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use this on double or float vectors
|
||||
* \return Length of Vector
|
||||
*/
|
||||
T Normalise() {
|
||||
T length = sqrt(x * x + y * y + z * z);
|
||||
|
||||
// Will also work for zero-sized vectors, but will change nothing
|
||||
if (length > 1e-08) {
|
||||
T InvLength = 1.0f / length;
|
||||
x *= InvLength;
|
||||
y *= InvLength;
|
||||
z *= InvLength;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Printing
|
||||
/////////////////////////////////////////
|
||||
|
||||
tString ToString() const {
|
||||
char buf[512];
|
||||
snprintf(buf, 512, "%f : %f : %f", x, y, z);
|
||||
tString str = buf;
|
||||
return str;
|
||||
}
|
||||
|
||||
tString ToFileString() const {
|
||||
char buf[512];
|
||||
snprintf(buf, 512, "%g %g %g", x, y, z);
|
||||
tString str = buf;
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_VECTOR3_H
|
||||
266
engines/hpl1/engine/math/hplMatrix.h
Normal file
266
engines/hpl1/engine/math/hplMatrix.h
Normal file
@@ -0,0 +1,266 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#ifndef HPL_MATRIX_H
|
||||
#define HPL_MATRIX_H
|
||||
|
||||
#include "hpl1/engine/math/Vector3.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
template<class T>
|
||||
class cMatrix {
|
||||
public:
|
||||
// The ways to reference the matrix
|
||||
// format is [row][col]
|
||||
union {
|
||||
T m[4][4];
|
||||
T v[16];
|
||||
};
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Constructors
|
||||
/////////////////////////////////////////
|
||||
|
||||
inline cMatrix() {
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline cMatrix(T *pA) {
|
||||
FromVec(pA);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline cMatrix(double *pA) {
|
||||
m[0][0] = (T)pA[0];
|
||||
m[0][1] = (T)pA[1];
|
||||
m[0][2] = (T)pA[2];
|
||||
m[0][3] = (T)pA[3];
|
||||
m[1][0] = (T)pA[4];
|
||||
m[1][1] = (T)pA[5];
|
||||
m[1][2] = (T)pA[6];
|
||||
m[1][3] = (T)pA[7];
|
||||
m[2][0] = (T)pA[8];
|
||||
m[2][1] = (T)pA[9];
|
||||
m[2][2] = (T)pA[10];
|
||||
m[2][3] = (T)pA[11];
|
||||
m[3][0] = (T)pA[12];
|
||||
m[3][1] = (T)pA[13];
|
||||
m[3][2] = (T)pA[14];
|
||||
m[3][3] = (T)pA[15];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline constexpr cMatrix(
|
||||
T a00, T a01, T a02, T a03,
|
||||
T a10, T a11, T a12, T a13,
|
||||
T a20, T a21, T a22, T a23,
|
||||
T a30, T a31, T a32, T a33) : m{
|
||||
{a00, a01, a02, a03},
|
||||
{a10, a11, a12, a13},
|
||||
{a20, a21, a22, a23},
|
||||
{a30, a31, a32, a33}} {
|
||||
}
|
||||
|
||||
static const cMatrix<T> Identity;
|
||||
static const cMatrix<T> Zero;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline bool operator==(const cMatrix<T> &aMtx) const {
|
||||
if (m[0][0] == aMtx.m[0][0] &&
|
||||
m[0][1] == aMtx.m[0][1] &&
|
||||
m[0][2] == aMtx.m[0][2] &&
|
||||
m[0][3] == aMtx.m[0][3] &&
|
||||
m[1][0] == aMtx.m[1][0] &&
|
||||
m[1][1] == aMtx.m[1][1] &&
|
||||
m[1][2] == aMtx.m[1][2] &&
|
||||
m[1][3] == aMtx.m[1][3] &&
|
||||
m[2][0] == aMtx.m[2][0] &&
|
||||
m[2][1] == aMtx.m[2][1] &&
|
||||
m[2][2] == aMtx.m[2][2] &&
|
||||
m[2][3] == aMtx.m[2][3] &&
|
||||
m[3][0] == aMtx.m[3][0] &&
|
||||
m[3][1] == aMtx.m[3][1] &&
|
||||
m[3][2] == aMtx.m[3][2] &&
|
||||
m[3][3] == aMtx.m[3][3]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline bool operator!=(const cMatrix<T> &aMtx) {
|
||||
return !(*this == aMtx);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline void FromVec(const T *pA) {
|
||||
m[0][0] = pA[0];
|
||||
m[0][1] = pA[1];
|
||||
m[0][2] = pA[2];
|
||||
m[0][3] = pA[3];
|
||||
m[1][0] = pA[4];
|
||||
m[1][1] = pA[5];
|
||||
m[1][2] = pA[6];
|
||||
m[1][3] = pA[7];
|
||||
m[2][0] = pA[8];
|
||||
m[2][1] = pA[9];
|
||||
m[2][2] = pA[10];
|
||||
m[2][3] = pA[11];
|
||||
m[3][0] = pA[12];
|
||||
m[3][1] = pA[13];
|
||||
m[3][2] = pA[14];
|
||||
m[3][3] = pA[15];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline void FromTranspose(const T *pA) {
|
||||
m[0][0] = pA[0];
|
||||
m[1][0] = pA[1];
|
||||
m[2][0] = pA[2];
|
||||
m[3][0] = pA[3];
|
||||
|
||||
m[0][1] = pA[4];
|
||||
m[1][1] = pA[5];
|
||||
m[2][1] = pA[6];
|
||||
m[3][1] = pA[7];
|
||||
|
||||
m[0][2] = pA[8];
|
||||
m[1][2] = pA[9];
|
||||
m[2][2] = pA[10];
|
||||
m[3][2] = pA[11];
|
||||
|
||||
m[0][3] = pA[12];
|
||||
m[1][3] = pA[13];
|
||||
m[2][3] = pA[14];
|
||||
m[3][3] = pA[15];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline cVector3<T> GetRight() const {
|
||||
/* @todo ??? */
|
||||
return cVector3<T>(m[0][0], m[0][1], m[0][2]);
|
||||
}
|
||||
|
||||
inline void SetRight(const cVector3<T> &avVec) {
|
||||
m[0][0] = avVec.x;
|
||||
m[0][1] = avVec.y;
|
||||
m[0][2] = avVec.z;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline cVector3<T> GetUp() const {
|
||||
/* @todo ??? */
|
||||
return cVector3<T>(m[1][0], m[1][1], m[1][2]);
|
||||
}
|
||||
|
||||
inline void SetUp(const cVector3<T> &avVec) {
|
||||
m[1][0] = avVec.x;
|
||||
m[1][1] = avVec.y;
|
||||
m[1][2] = avVec.z;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline cVector3<T> GetForward() const {
|
||||
/* @todo ??? */
|
||||
return cVector3<T>(m[2][0], m[2][1], m[2][2]);
|
||||
}
|
||||
|
||||
inline void SetForward(const cVector3<T> &avVec) {
|
||||
m[2][0] = avVec.x;
|
||||
m[2][1] = avVec.y;
|
||||
m[2][2] = avVec.z;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline cVector3<T> GetTranslation() const {
|
||||
/* @todo ??? */
|
||||
return cVector3<T>(m[0][3], m[1][3], m[2][3]);
|
||||
}
|
||||
|
||||
inline void SetTranslation(const cVector3<T> &avTrans) {
|
||||
m[0][3] = avTrans.x;
|
||||
m[1][3] = avTrans.y;
|
||||
m[2][3] = avTrans.z;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline cMatrix<T> GetRotation() const {
|
||||
return cMatrix<T>(m[0][0], m[0][1], m[0][2], 0,
|
||||
m[1][0], m[1][1], m[1][2], 0,
|
||||
m[2][0], m[2][1], m[2][2], 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline cMatrix<T> GetTranspose() const {
|
||||
return cMatrix<T>(m[0][0], m[1][0], m[2][0], m[3][0],
|
||||
m[0][1], m[1][1], m[2][1], m[3][1],
|
||||
m[0][2], m[1][2], m[2][2], m[3][2],
|
||||
m[0][3], m[1][3], m[2][3], m[3][3]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
tString ToString() {
|
||||
char buf[512];
|
||||
snprintf(buf, 512, "[%f : %f : %f : %f] [%f : %f : %f : %f] [%f : %f : %f : %f] [%f : %f : %f : %f]",
|
||||
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
return buf;
|
||||
}
|
||||
|
||||
tString ToFileString() {
|
||||
char buf[512];
|
||||
snprintf(buf, 512, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
|
||||
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
return buf;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace hpl
|
||||
|
||||
#endif // HPL_MATRIX_H
|
||||
Reference in New Issue
Block a user