diff --git a/CMakeLists.txt b/CMakeLists.txt index f5ece05bc..e96249ff3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 917963e48..7ff43de36 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -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]++; diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 5f675b40c..7988ab51f 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -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; } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 5750747dd..1874d0ab8 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -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 } }; diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index ea75dd39a..31c88e46e 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -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]++; diff --git a/src/gl/utility/gl_geometric.cpp b/src/gl/utility/gl_geometric.cpp index 6db10af74..13c205194 100644 --- a/src/gl/utility/gl_geometric.cpp +++ b/src/gl/utility/gl_geometric.cpp @@ -35,243 +35,27 @@ #include #include #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_d = (float)plane.fD(); + 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; } diff --git a/src/gl/utility/gl_geometric.h b/src/gl/utility/gl_geometric.h index 243361d41..a25ae9f9f 100644 --- a/src/gl/utility/gl_geometric.h +++ b/src/gl/utility/gl_geometric.h @@ -37,142 +37,27 @@ #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(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; } + 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(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 D() { return m_d; } + 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; - float m_d; + FVector3 m_normal; + float m_d; }; class Matrix3x4 // used like a 4x4 matrix with the last row always being (0,0,0,1) @@ -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 diff --git a/src/vectors.h b/src/vectors.h index 1852609f2..0178e28bb 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -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; }