2016-09-14 18:01:13 +00:00
|
|
|
/*
|
|
|
|
** 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.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
#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)
|
|
|
|
{
|
2016-04-03 09:40:14 +00:00
|
|
|
SetX((float)v->fX());
|
|
|
|
SetY((float)v->fY());
|
2013-06-23 07:49:34 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-05-01 10:39:08 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
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
|