gzdoom-gles/src/gl/utility/gl_geometric.h
Christoph Oelckers 8b6e09ca09 - changed the license of the OpenGL renderer to LGPL v3.
This was done to clean up the license and to ensure that any commercial fork of the engine has to obey the far stricter requirements concerning source distribution. The old license was compatible with GPLv2 whereas combining GPLv2 and LGPLv3 force a license upgrade to GPLv3. The license of code that originates from ZDoomGL has not been changed.
2016-09-14 20:01:13 +02:00

294 lines
7.7 KiB
C++

/*
** gl_geometric.h
**
**---------------------------------------------------------------------------
** Copyright 2003 Timothy Stump
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#ifndef __GL_GEOM
#define __GL_GEOM
#include "math.h"
#include "r_defs.h"
class Vector
{
public:
Vector()
{
SetX(0.f);
SetY(1.f);
SetZ(0.f);
m_length = 1.f;
}
Vector(float x, float y, float z)
{
SetX(x);
SetY(y);
SetZ(z);
m_length=-1.0f;
}
Vector(float *v)
{
SetX(v[0]);
SetY(v[1]);
SetZ(v[2]);
m_length=-1.0f;
}
Vector(vertex_t * v)
{
SetX((float)v->fX());
SetY((float)v->fY());
SetZ(0);
}
void Normalize()
{
float l = 1.f / Length();
SetX(X() * l);
SetY(Y() * l);
SetZ(Z() * l);
m_length=1.0f;
}
void UpdateLength()
{
m_length = sqrtf((X() * X()) + (Y() * Y()) + (Z() * Z()));
}
void Set(float *v)
{
SetX(v[0]);
SetY(v[1]);
SetZ(v[2]);
m_length=-1.0f;
}
void Set(float x, float y, float z)
{
SetX(x);
SetY(y);
SetZ(z);
m_length=-1.0f;
}
float Length()
{
if (m_length<0.0f) UpdateLength();
return m_length;
}
float Dist(Vector &v)
{
Vector t(X() - v.X(), Y() - v.Y(), Z() - v.Z());
return t.Length();
}
float Dot(Vector &v)
{
return (X() * v.X()) + (Y() * v.Y()) + (Z() * v.Z());
}
Vector Cross(Vector &v);
Vector operator- (Vector &v);
Vector operator+ (Vector &v);
Vector operator* (float f);
Vector operator/ (float f);
bool operator== (Vector &v);
bool operator!= (Vector &v) { return !((*this) == v); }
void GetRightUp(Vector &up, Vector &right);
float operator[] (int index) const { return m_vec[index]; }
float &operator[] (int index) { return m_vec[index]; }
float X() const { return m_vec[0]; }
float Y() const { return m_vec[1]; }
float Z() const { return m_vec[2]; }
void SetX(float x) { m_vec[0] = x; }
void SetY(float y) { m_vec[1] = y; }
void SetZ(float z) { m_vec[2] = z; }
void Scale(float scale);
Vector ProjectVector(Vector &a);
Vector ProjectPlane(Vector &right, Vector &up);
protected:
float m_vec[3];
float m_length;
};
class Plane
{
public:
Plane()
{
m_normal.Set(0.f, 1.f, 0.f);
m_d = 0.f;
}
void Init(float *v1, float *v2, float *v3);
void Init(float a, float b, float c, float d);
void Init(float *verts, int numVerts);
void Set(secplane_t &plane);
float DistToPoint(float x, float y, float z);
bool PointOnSide(float x, float y, float z);
bool PointOnSide(Vector &v) { return PointOnSide(v.X(), v.Y(), v.Z()); }
bool ValidNormal() { return m_normal.Length() == 1.f; }
float A() { return m_normal.X(); }
float B() { return m_normal.Y(); }
float C() { return m_normal.Z(); }
float D() { return m_d; }
const Vector &Normal() const { return m_normal; }
protected:
Vector m_normal;
float m_d;
};
class Matrix3x4 // used like a 4x4 matrix with the last row always being (0,0,0,1)
{
float m[3][4];
public:
void MakeIdentity()
{
memset(m, 0, sizeof(m));
m[0][0] = m[1][1] = m[2][2] = 1.f;
}
void Translate(float x, float y, float z)
{
m[0][3] = m[0][0]*x + m[0][1]*y + m[0][2]*z + m[0][3];
m[1][3] = m[1][0]*x + m[1][1]*y + m[1][2]*z + m[1][3];
m[2][3] = m[2][0]*x + m[2][1]*y + m[2][2]*z + m[2][3];
}
void Scale(float x, float y, float z)
{
m[0][0] *=x;
m[1][0] *=x;
m[2][0] *=x;
m[0][1] *=y;
m[1][1] *=y;
m[2][1] *=y;
m[0][2] *=z;
m[1][2] *=z;
m[2][2] *=z;
}
void Rotate(float ax, float ay, float az, float angle)
{
Matrix3x4 m1;
Vector axis(ax, ay, az);
axis.Normalize();
double c = cos(angle * M_PI/180.), s = sin(angle * M_PI/180.), t = 1 - c;
double sx = s*axis.X(), sy = s*axis.Y(), sz = s*axis.Z();
double tx, ty, txx, tyy, u, v;
tx = t*axis.X();
m1.m[0][0] = float( (txx=tx*axis.X()) + c );
m1.m[0][1] = float( (u=tx*axis.Y()) - sz);
m1.m[0][2] = float( (v=tx*axis.Z()) + sy);
ty = t*axis.Y();
m1.m[1][0] = float( u + sz);
m1.m[1][1] = float( (tyy=ty*axis.Y()) + c );
m1.m[1][2] = float( (u=ty*axis.Z()) - sx);
m1.m[2][0] = float( v - sy);
m1.m[2][1] = float( u + sx);
m1.m[2][2] = float( (t-txx-tyy) + c );
m1.m[0][3] = 0.f;
m1.m[1][3] = 0.f;
m1.m[2][3] = 0.f;
*this = (*this) * m1;
}
Matrix3x4 operator *(const Matrix3x4 &other)
{
Matrix3x4 result;
result.m[0][0] = m[0][0]*other.m[0][0] + m[0][1]*other.m[1][0] + m[0][2]*other.m[2][0];
result.m[0][1] = m[0][0]*other.m[0][1] + m[0][1]*other.m[1][1] + m[0][2]*other.m[2][1];
result.m[0][2] = m[0][0]*other.m[0][2] + m[0][1]*other.m[1][2] + m[0][2]*other.m[2][2];
result.m[0][3] = m[0][0]*other.m[0][3] + m[0][1]*other.m[1][3] + m[0][2]*other.m[2][3] + m[0][3];
result.m[1][0] = m[1][0]*other.m[0][0] + m[1][1]*other.m[1][0] + m[1][2]*other.m[2][0];
result.m[1][1] = m[1][0]*other.m[0][1] + m[1][1]*other.m[1][1] + m[1][2]*other.m[2][1];
result.m[1][2] = m[1][0]*other.m[0][2] + m[1][1]*other.m[1][2] + m[1][2]*other.m[2][2];
result.m[1][3] = m[1][0]*other.m[0][3] + m[1][1]*other.m[1][3] + m[1][2]*other.m[2][3] + m[1][3];
result.m[2][0] = m[2][0]*other.m[0][0] + m[2][1]*other.m[1][0] + m[2][2]*other.m[2][0];
result.m[2][1] = m[2][0]*other.m[0][1] + m[2][1]*other.m[1][1] + m[2][2]*other.m[2][1];
result.m[2][2] = m[2][0]*other.m[0][2] + m[2][1]*other.m[1][2] + m[2][2]*other.m[2][2];
result.m[2][3] = m[2][0]*other.m[0][3] + m[2][1]*other.m[1][3] + m[2][2]*other.m[2][3] + m[2][3];
return result;
}
Vector operator *(const Vector &vec)
{
Vector result;
result.SetX(vec.X()*m[0][0] + vec.Y()*m[0][1] + vec.Z()*m[0][2] + m[0][3]);
result.SetY(vec.X()*m[1][0] + vec.Y()*m[1][1] + vec.Z()*m[1][2] + m[1][3]);
result.SetZ(vec.X()*m[2][0] + vec.Y()*m[2][1] + vec.Z()*m[2][2] + m[2][3]);
return result;
}
FVector3 operator *(const FVector3 &vec)
{
FVector3 result;
result.X = vec.X*m[0][0] + vec.Y*m[0][1] + vec.Z*m[0][2] + m[0][3];
result.Y = vec.X*m[1][0] + vec.Y*m[1][1] + vec.Z*m[1][2] + m[1][3];
result.Z = vec.X*m[2][0] + vec.Y*m[2][1] + vec.Z*m[2][2] + m[2][3];
return result;
}
void MultiplyVector(float *f3 , float *f3o)
{
float x = f3[0] * m[0][0] + f3[1] * m[0][1] + f3[2] * m[0][2] + m[0][3];
float y = f3[0] * m[1][0] + f3[1] * m[1][1] + f3[2] * m[1][2] + m[1][3];
float z = f3[0] * m[2][0] + f3[1] * m[2][1] + f3[2] * m[2][2] + m[2][3];
f3o[2] = z; f3o[1] = y; f3o[0] = x;
}
};
#endif