mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 06:53:40 +00:00
- removed the Vector class in the GL renderer and replaced all its uses with FVector3.
- optimized the math to get a plane equation from a linedef. The original code used a generic algorithm that knew nothing about the fact that Doom walls are always perfectly vertical. With this knowledge the plane calculation can be reduced to a lot less code because retrieving the normal is trivial in this special case. - use the SSE2 rsqrtss instruction to calculate a wall's length, because this is by far the most frequent use of square roots in the GL renderer. So far this is only active on x64, it may be activated on 32 bit later as well, but only after it has been decided if 32 bit builds should be x87 or SSE2. # Conflicts: # src/gl/dynlights/gl_dynlight.cpp # Conflicts: # src/g_shared/a_dynlightdata.cpp
This commit is contained in:
parent
ef3421eee5
commit
4cd0d3d454
8 changed files with 136 additions and 428 deletions
|
@ -177,6 +177,7 @@ if( MSVC )
|
|||
# Use SSE 2 as minimum always as the true color drawers needs it for __vectorcall
|
||||
#set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2") # This is already the default
|
||||
|
||||
|
||||
# if( CMAKE_SIZEOF_VOID_P MATCHES "4")
|
||||
# # SSE2 option (to allow x87 in 32 bit and disallow extended feature sets which have not yet been checked for precision)
|
||||
# option (ZDOOM_USE_SSE2 "Use SSE2 instruction set")
|
||||
|
|
|
@ -372,10 +372,10 @@ void FRenderState::DrawColormapOverlay()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right,
|
||||
bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, FVector3 & nearPt, FVector3 & up, FVector3 & right,
|
||||
float & scale, bool checkside, bool additive)
|
||||
{
|
||||
Vector fn, pos;
|
||||
FVector3 fn, pos;
|
||||
|
||||
DVector3 lpos = light->PosRelative(group);
|
||||
|
||||
|
@ -398,16 +398,12 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
|
|||
// project light position onto plane (find closest point on plane)
|
||||
|
||||
|
||||
pos.Set(lpos.X, lpos.Z, lpos.Y);
|
||||
pos = { (float)lpos.X, (float)lpos.Z, (float)lpos.Y };
|
||||
fn = p.Normal();
|
||||
fn.GetRightUp(right, up);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
nearPt = pos + fn * dist;
|
||||
#else
|
||||
Vector tmpVec = fn * dist;
|
||||
FVector3 tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
#endif
|
||||
|
||||
float cs = 1.0f - (dist / radius);
|
||||
if (additive) cs *= 0.2f; // otherwise the light gets too strong.
|
||||
|
@ -417,13 +413,11 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
|
|||
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
Vector v;
|
||||
|
||||
gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
v.Set(r, g, b);
|
||||
r = v.Length() - r;
|
||||
g = v.Length() - g;
|
||||
b = v.Length() - b;
|
||||
float length = float(FVector3(r, g, b).Length());
|
||||
r = length - r;
|
||||
g = length - g;
|
||||
b = length - b;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -564,7 +558,7 @@ void GLWall::RenderFogBoundaryCompat()
|
|||
void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
|
||||
{
|
||||
Plane p;
|
||||
Vector nearPt, up, right, t1;
|
||||
FVector3 nearPt, up, right, t1;
|
||||
float scale;
|
||||
|
||||
FLightNode * node = sub->lighthead;
|
||||
|
@ -604,11 +598,11 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
|
|||
ptr->x = vt->fX();
|
||||
ptr->z = plane.plane.ZatPoint(vt) + dz;
|
||||
ptr->y = vt->fY();
|
||||
t1.Set(ptr->x, ptr->z, ptr->y);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
t1 = { ptr->x, ptr->z, ptr->y };
|
||||
FVector3 nearToVert = t1 - nearPt;
|
||||
|
||||
ptr->u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
ptr->v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
ptr->u = ((nearToVert | right) * scale) + 0.5f;
|
||||
ptr->v = ((nearToVert | up) * scale) + 0.5f;
|
||||
ptr++;
|
||||
}
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
@ -660,10 +654,10 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass)
|
|||
{
|
||||
float vtx[] = { glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2 };
|
||||
Plane p;
|
||||
Vector nearPt, up, right;
|
||||
FVector3 nearPt, up, right;
|
||||
float scale;
|
||||
|
||||
p.Init(vtx, 4);
|
||||
p.Set(&glseg);
|
||||
|
||||
if (!p.ValidNormal())
|
||||
{
|
||||
|
@ -675,15 +669,15 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass)
|
|||
return false;
|
||||
}
|
||||
|
||||
Vector t1;
|
||||
FVector3 t1;
|
||||
int outcnt[4] = { 0,0,0,0 };
|
||||
|
||||
for (int i = 0; i<4; i++)
|
||||
{
|
||||
t1.Set(&vtx[i * 3]);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
t1 = &vtx[i * 3];
|
||||
FVector3 nearToVert = t1 - nearPt;
|
||||
tcs[i].u = ((nearToVert | right) * scale) + 0.5f;
|
||||
tcs[i].v = ((nearToVert | up) * scale) + 0.5f;
|
||||
|
||||
// quick check whether the light touches this polygon
|
||||
if (tcs[i].u<0) outcnt[0]++;
|
||||
|
|
|
@ -97,12 +97,12 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
|
|||
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
Vector v;
|
||||
DVector3 v(r, g, b);
|
||||
float length = (float)v.Length();
|
||||
|
||||
v.Set(r, g, b);
|
||||
r = v.Length() - r;
|
||||
g = v.Length() - g;
|
||||
b = v.Length() - b;
|
||||
r = length - r;
|
||||
g = length - g;
|
||||
b = length - b;
|
||||
i = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
//==========================================================================
|
||||
#include "r_defs.h"
|
||||
#include "r_data/renderstyle.h"
|
||||
#include "textures/textures.h"
|
||||
#include "gl/renderer/gl_colormap.h"
|
||||
|
||||
|
@ -66,8 +67,15 @@ struct GLSeg
|
|||
// we do not use the vector math inlines here because they are not optimized for speed but accuracy in the playsim
|
||||
float x = y2 - y1;
|
||||
float y = x1 - x2;
|
||||
#if defined(__amd64__) || defined(_M_X64)
|
||||
__m128 v;
|
||||
v.m128_f32[0] = x*x + y*y;
|
||||
float ilength = _mm_rsqrt_ss(v).m128_f32[0];
|
||||
return FVector3(x * ilength, 0, y * ilength);
|
||||
#else
|
||||
float length = sqrtf(x*x + y*y);
|
||||
return FVector3(x / length, 0, y / length);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -74,12 +74,14 @@ void GLWall::SetupLights()
|
|||
Plane p;
|
||||
|
||||
lightdata.Clear();
|
||||
p.Init(vtx,4);
|
||||
p.Set(&glseg);
|
||||
|
||||
/*
|
||||
if (!p.ValidNormal())
|
||||
{
|
||||
return;
|
||||
}
|
||||
*/
|
||||
FLightNode *node;
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
|
@ -103,8 +105,6 @@ void GLWall::SetupLights()
|
|||
{
|
||||
iter_dlight++;
|
||||
|
||||
Vector fn, pos;
|
||||
|
||||
DVector3 posrel = node->lightsource->PosRelative(seg->frontsector);
|
||||
float x = posrel.X;
|
||||
float y = posrel.Y;
|
||||
|
@ -112,29 +112,31 @@ void GLWall::SetupLights()
|
|||
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||
float radius = node->lightsource->GetRadius();
|
||||
float scale = 1.0f / ((2.f * radius) - dist);
|
||||
FVector3 fn, pos;
|
||||
|
||||
if (radius > 0.f && dist < radius)
|
||||
{
|
||||
Vector nearPt, up, right;
|
||||
FVector3 nearPt, up, right;
|
||||
|
||||
pos = { x, z, y };
|
||||
fn = p.Normal();
|
||||
|
||||
pos.Set(x,z,y);
|
||||
fn=p.Normal();
|
||||
fn.GetRightUp(right, up);
|
||||
|
||||
Vector tmpVec = fn * dist;
|
||||
FVector3 tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
|
||||
Vector t1;
|
||||
FVector3 t1;
|
||||
int outcnt[4]={0,0,0,0};
|
||||
texcoord tcs[4];
|
||||
|
||||
// do a quick check whether the light touches this polygon
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
t1.Set(&vtx[i*3]);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
t1 = FVector3(&vtx[i*3]);
|
||||
FVector3 nearToVert = t1 - nearPt;
|
||||
tcs[i].u = ((nearToVert | right) * scale) + 0.5f;
|
||||
tcs[i].v = ((nearToVert | up) * scale) + 0.5f;
|
||||
|
||||
if (tcs[i].u<0) outcnt[0]++;
|
||||
if (tcs[i].u>1) outcnt[1]++;
|
||||
|
|
|
@ -35,243 +35,27 @@
|
|||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include "gl/utility/gl_geometric.h"
|
||||
#include "gl/scene/gl_wall.h"
|
||||
|
||||
static Vector axis[3] =
|
||||
|
||||
void Plane::Set(GLSeg *seg)
|
||||
{
|
||||
Vector(1.0f, 0.0f, 0.0f),
|
||||
Vector(0.0f, 1.0f, 0.0f),
|
||||
Vector(0.0f, 0.0f, 1.0f)
|
||||
};
|
||||
|
||||
|
||||
|
||||
Vector Vector::Cross(Vector &v)
|
||||
{
|
||||
float x, y, z;
|
||||
Vector cp;
|
||||
|
||||
x = Y() * v.Z() - Z() * v.Y();
|
||||
y = Z() * v.X() - X() * v.Z();
|
||||
z = X() * v.Y() - Y() * v.X();
|
||||
|
||||
cp.Set(x, y, z);
|
||||
|
||||
return cp;
|
||||
m_normal = seg->Normal();
|
||||
m_d = m_normal | FVector3(-seg->x1, 0, -seg->y1);
|
||||
}
|
||||
|
||||
|
||||
Vector Vector::operator- (Vector &v)
|
||||
{
|
||||
float x, y, z;
|
||||
Vector vec;
|
||||
|
||||
x = X() - v.X();
|
||||
y = Y() - v.Y();
|
||||
z = Z() - v.Z();
|
||||
|
||||
vec.Set(x, y, z);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
Vector Vector::operator+ (Vector &v)
|
||||
{
|
||||
float x, y, z;
|
||||
Vector vec;
|
||||
|
||||
x = X() + v.X();
|
||||
y = Y() + v.Y();
|
||||
z = Z() + v.Z();
|
||||
|
||||
vec.Set(x, y, z);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
Vector Vector::operator* (float f)
|
||||
{
|
||||
Vector vec(X(), Y(), Z());
|
||||
|
||||
vec.Scale(f);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
Vector Vector::operator/ (float f)
|
||||
{
|
||||
Vector vec(X(), Y(), Z());
|
||||
|
||||
vec.Scale(1.f / f);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
bool Vector::operator== (Vector &v)
|
||||
{
|
||||
return X() == v.X() && Y() == v.Y() && Z() == v.Z();
|
||||
}
|
||||
|
||||
|
||||
void Vector::GetRightUp(Vector &right, Vector &up)
|
||||
{
|
||||
Vector n(X(), Y(), Z());
|
||||
Vector fn(fabsf(n.X()), fabsf(n.Y()), fabsf(n.Z()));
|
||||
int major = 0;
|
||||
|
||||
if (fn[1] > fn[major]) major = 1;
|
||||
if (fn[2] > fn[major]) major = 2;
|
||||
|
||||
// build right vector by hand
|
||||
if (fabsf(fn[0]-1.0f) < FLT_EPSILON || fabsf(fn[1]-1.0f) < FLT_EPSILON || fabsf(fn[2]-1.0f) < FLT_EPSILON)
|
||||
{
|
||||
if (major == 0 && n[0] > 0.f)
|
||||
{
|
||||
right.Set(0.f, 0.f, -1.f);
|
||||
}
|
||||
else if (major == 0)
|
||||
{
|
||||
right.Set(0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
if (major == 1 || (major == 2 && n[2] > 0.f))
|
||||
{
|
||||
right.Set(1.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
if (major == 2 && n[2] < 0.0f)
|
||||
{
|
||||
right.Set(-1.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
right = axis[major].Cross(n);
|
||||
}
|
||||
|
||||
up = n.Cross(right);
|
||||
right.Normalize();
|
||||
up.Normalize();
|
||||
}
|
||||
|
||||
|
||||
void Vector::Scale(float scale)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
x = X() * scale;
|
||||
y = Y() * scale;
|
||||
z = Z() * scale;
|
||||
|
||||
Set(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
Vector Vector::ProjectVector(Vector &a)
|
||||
{
|
||||
Vector res, b;
|
||||
|
||||
b.Set(X(), Y(), Z());
|
||||
res.Set(a.X(), a.Y(), a.Z());
|
||||
|
||||
res.Scale(a.Dot(b) / a.Dot(a));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Vector Vector::ProjectPlane(Vector &right, Vector &up)
|
||||
{
|
||||
Vector src(X(), Y(), Z());
|
||||
Vector t1, t2;
|
||||
|
||||
t1 = src.ProjectVector(right);
|
||||
t2 = src.ProjectVector(up);
|
||||
|
||||
return t1 + t2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void Plane::Init(float *v1, float *v2, float *v3)
|
||||
{
|
||||
Vector vec1, vec2, vec3;
|
||||
|
||||
vec1.Set(v1);
|
||||
vec2.Set(v2);
|
||||
vec3.Set(v3);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
m_normal = (vec2 - vec1).Cross(vec3 - vec1);
|
||||
#else
|
||||
Vector tmpVec = vec3 - vec1;
|
||||
m_normal = (vec2 - vec1).Cross(tmpVec);
|
||||
#endif
|
||||
m_normal.Normalize();
|
||||
m_d = vec3.Dot(m_normal) * -1.f;
|
||||
}
|
||||
|
||||
|
||||
#define FNOTEQUAL(a, b) (fabsf(a - b) > 0.001f)
|
||||
void Plane::Init(float *verts, int numVerts)
|
||||
{
|
||||
float *v[3], *t;
|
||||
int i, curVert;
|
||||
|
||||
if (numVerts < 3) return;
|
||||
|
||||
curVert = 1;
|
||||
v[0] = verts + 0;
|
||||
for (i = 1; i < numVerts; i++)
|
||||
{
|
||||
t = verts + (i * 3);
|
||||
if (FNOTEQUAL(t[0], v[curVert - 1][0]) || FNOTEQUAL(t[1], v[curVert - 1][1]) || FNOTEQUAL(t[2], v[curVert - 1][2]))
|
||||
{
|
||||
v[curVert] = t;
|
||||
curVert++;
|
||||
}
|
||||
if (curVert == 3) break;
|
||||
}
|
||||
|
||||
if (curVert != 3)
|
||||
{
|
||||
// degenerate triangle, no valid normal
|
||||
return;
|
||||
}
|
||||
|
||||
Init(v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
|
||||
void Plane::Init(float a, float b, float c, float d)
|
||||
{
|
||||
m_normal.Set(a, b, c);
|
||||
m_d = d / m_normal.Length();
|
||||
m_normal.Normalize();
|
||||
}
|
||||
|
||||
|
||||
void Plane::Set(secplane_t &plane)
|
||||
{
|
||||
m_normal.Set((float)plane.Normal().X, (float)plane.Normal().Z, (float)plane.Normal().Y);
|
||||
//m_normal.Normalize(); the vector is already normalized
|
||||
m_normal = { (float)plane.Normal().X, (float)plane.Normal().Z, (float)plane.Normal().Y };
|
||||
m_d = (float)plane.fD();
|
||||
}
|
||||
|
||||
|
||||
float Plane::DistToPoint(float x, float y, float z)
|
||||
{
|
||||
Vector p;
|
||||
FVector3 p(x, y, z);
|
||||
|
||||
p.Set(x, y, z);
|
||||
|
||||
return m_normal.Dot(p) + m_d;
|
||||
return (m_normal | p) + m_d;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,141 +37,26 @@
|
|||
#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;
|
||||
};
|
||||
|
||||
struct GLSeg;
|
||||
|
||||
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(GLSeg *seg);
|
||||
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; }
|
||||
bool PointOnSide(FVector3 &v) { return PointOnSide(v.X, v.Y, v.Z); }
|
||||
bool ValidNormal() { return m_normal.LengthSquared() == 1.f; }
|
||||
|
||||
float A() { return m_normal.X(); }
|
||||
float B() { return m_normal.Y(); }
|
||||
float C() { return m_normal.Z(); }
|
||||
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; }
|
||||
const FVector3 &Normal() const { return m_normal; }
|
||||
protected:
|
||||
Vector m_normal;
|
||||
FVector3 m_normal;
|
||||
float m_d;
|
||||
};
|
||||
|
||||
|
@ -213,21 +98,21 @@ public:
|
|||
{
|
||||
Matrix3x4 m1;
|
||||
|
||||
Vector axis(ax, ay, az);
|
||||
axis.Normalize();
|
||||
FVector3 axis(ax, ay, az);
|
||||
axis.MakeUnit();
|
||||
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 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);
|
||||
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();
|
||||
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[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);
|
||||
|
@ -262,16 +147,6 @@ public:
|
|||
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;
|
||||
|
@ -281,14 +156,6 @@ public:
|
|||
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
|
||||
|
|
|
@ -325,6 +325,11 @@ struct TVector3
|
|||
{
|
||||
}
|
||||
|
||||
TVector3(vec_t *o)
|
||||
: X(o[0]), Y(o[1]), Z(o[2])
|
||||
{
|
||||
}
|
||||
|
||||
TVector3 (const TVector3 &other)
|
||||
: X(other.X), Y(other.Y), Z(other.Z)
|
||||
{
|
||||
|
@ -520,6 +525,53 @@ struct TVector3
|
|||
return Vector2(v2.X - v3.X, v2.Y - v3.Y);
|
||||
}
|
||||
|
||||
void GetRightUp(TVector3 &right, TVector3 &up)
|
||||
{
|
||||
TVector3 n(X, Y, Z);
|
||||
TVector3 fn(fabs(n.X), fabs(n.Y), fabs(n.Z));
|
||||
int major = 0;
|
||||
|
||||
if (fn[1] > fn[major]) major = 1;
|
||||
if (fn[2] > fn[major]) major = 2;
|
||||
|
||||
// build right vector by hand
|
||||
if (fabs(fn[0] - 1.0f) < FLT_EPSILON || fabs(fn[1] - 1.0f) < FLT_EPSILON || fabs(fn[2] - 1.0f) < FLT_EPSILON)
|
||||
{
|
||||
if (major == 0 && n[0] > 0.f)
|
||||
{
|
||||
right = { 0.f, 0.f, -1.f };
|
||||
}
|
||||
else if (major == 0)
|
||||
{
|
||||
right = { 0.f, 0.f, 1.f };
|
||||
}
|
||||
|
||||
if (major == 1 || (major == 2 && n[2] > 0.f))
|
||||
{
|
||||
right = { 1.f, 0.f, 0.f };
|
||||
}
|
||||
|
||||
if (major == 2 && n[2] < 0.0f)
|
||||
{
|
||||
right = { -1.f, 0.f, 0.f };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static TVector3 axis[3] =
|
||||
{
|
||||
{ 1.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 1.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 1.0f }
|
||||
};
|
||||
|
||||
right = axis[major] ^ n;
|
||||
}
|
||||
|
||||
up = n ^right;
|
||||
right.MakeUnit();;
|
||||
up.MakeUnit();
|
||||
}
|
||||
|
||||
|
||||
// Returns the angle (in radians) that the ray (0,0)-(X,Y) faces
|
||||
|
@ -542,7 +594,7 @@ struct TVector3
|
|||
{
|
||||
double len = Length();
|
||||
if (len != 0) len = 1 / len;
|
||||
return *this * len;
|
||||
return *this * (vec_t)len;
|
||||
}
|
||||
|
||||
// Scales this vector into a unit vector
|
||||
|
@ -550,7 +602,7 @@ struct TVector3
|
|||
{
|
||||
double len = Length();
|
||||
if (len != 0) len = 1 / len;
|
||||
*this *= len;
|
||||
*this *= (vec_t)len;
|
||||
}
|
||||
|
||||
// Resizes this vector to be the specified length (if it is not 0)
|
||||
|
@ -582,7 +634,7 @@ struct TVector3
|
|||
}
|
||||
|
||||
// Dot product
|
||||
double operator | (const TVector3 &other) const
|
||||
vec_t operator | (const TVector3 &other) const
|
||||
{
|
||||
return X*other.X + Y*other.Y + Z*other.Z;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue