]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - contrib/bobtoolz/DPlane.cpp
q3map2: fix prt loading for vis computation when using -prtfile
[xonotic/netradiant.git] / contrib / bobtoolz / DPlane.cpp
index 2fe24ecfadb30e6ba1c802a941dbbb8171b054ee..1258e2bcf73c6f25f18322bd6cc1de4c0c0dad6e 100644 (file)
-/*\r
-BobToolz plugin for GtkRadiant\r
-Copyright (C) 2001 Gordon Biggans\r
-\r
-This library is free software; you can redistribute it and/or\r
-modify it under the terms of the GNU Lesser General Public\r
-License as published by the Free Software Foundation; either\r
-version 2.1 of the License, or (at your option) any later version.\r
-\r
-This library is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-Lesser General Public License for more details.\r
-\r
-You should have received a copy of the GNU Lesser General Public\r
-License along with this library; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
-*/\r
-\r
-// DPlane.cpp: implementation of the DPlane class.\r
-//\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-#include "StdAfx.h"\r
-#include "DPlane.h"\r
-#include "DWinding.h"\r
-#include "misc.h"\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Construction/Destruction\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-DPlane::DPlane(vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData* texData)\r
-{\r
-       MakeNormal( va, vb, vc, normal );\r
-       if(VectorNormalize(normal, normal) == 0)        // normalizes and returns length\r
-               Sys_ERROR("DPlane::DPlane: Bad Normal.\n");\r
-\r
-       _d = (normal[0]*va[0]) + (normal[1]*va[1]) + (normal[2]*va[2]);\r
-\r
-       VectorCopy(va, points[0]);\r
-       VectorCopy(vb, points[1]);\r
-       VectorCopy(vc, points[2]);\r
-\r
-       m_bChkOk = TRUE;\r
-\r
-       if(texData)\r
-               memcpy(&texInfo, texData, sizeof(_QERFaceData));\r
-       else\r
-               FillDefaultTexture(&texInfo, points[0], points[1], points[2], "textures/common/caulk");\r
-}\r
-\r
-DPlane::~DPlane()\r
-{\r
-\r
-}\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Implementation\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-vec_t DPlane::DistanceToPoint(vec3_t pnt)\r
-{\r
-       vec3_t tmp;\r
-       VectorSubtract(pnt, points[0], tmp);\r
-       return DotProduct(tmp, normal);\r
-}\r
-\r
-bool DPlane::PlaneIntersection(DPlane *pl1, DPlane *pl2, vec3_t out)\r
-{\r
-       float a1, a2, a3;\r
-       float b1, b2, b3;\r
-       float c1, c2, c3;\r
-       \r
-       a1 = normal[0];                 a2 = normal[1];                 a3 = normal[2];\r
-       b1 = pl1->normal[0];    b2 = pl1->normal[1];    b3 = pl1->normal[2];\r
-       c1 = pl2->normal[0];    c2 = pl2->normal[1];    c3 = pl2->normal[2];\r
-\r
-       float d = Determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);\r
-\r
-       if(d == 0)\r
-               return FALSE;\r
-       \r
-       float v1 = _d;\r
-       float v2 = pl1->_d;\r
-       float v3 = pl2->_d;\r
-\r
-       float d1 = Determinant3x3(v1, a2, a3, v2, b2, b3, v3, c2, c3);\r
-       float d2 = Determinant3x3(a1, v1, a3, b1, v2, b3, c1, v3, c3);\r
-       float d3 = Determinant3x3(a1, a2, v1, b1, b2, v2, c1, c2, v3);\r
-\r
-       out[0] = d1/d;  \r
-       out[1] = d2/d;  \r
-       out[2] = d3/d;  \r
-\r
-       return TRUE;\r
-}\r
-\r
-bool DPlane::IsRedundant(list<DPoint*>& pointList)\r
-{\r
-       int cnt = 0;\r
-\r
-       //list<DPoint *>::const_iterator point=pointList.begin();\r
-       for(list<DPoint *>::const_iterator point=pointList.begin(); point!=pointList.end(); point++)\r
-       {\r
-                if(fabs(DistanceToPoint((*point)->_pnt)) < MAX_ROUND_ERROR)\r
-                        cnt++;\r
-\r
-                if(cnt == 3)\r
-                        return FALSE;\r
-       }\r
-       return TRUE;\r
-}\r
-\r
-bool DPlane::operator == (DPlane& other)\r
-{\r
-       vec3_t chk;\r
-       VectorSubtract(other.normal, normal, chk);\r
-       if(fabs(VectorLength(chk)) > MAX_ROUND_ERROR)\r
-               return FALSE;\r
-\r
-       if(fabs(other._d - _d) > MAX_ROUND_ERROR)\r
-               return FALSE;\r
-\r
-       return TRUE;\r
-}\r
-\r
-bool DPlane::operator != (DPlane& other)\r
-{\r
-       vec3_t chk;\r
-       VectorAdd(other.normal, normal, chk);\r
-       if(fabs(VectorLength(chk)) > MAX_ROUND_ERROR)\r
-               return FALSE;\r
-\r
-       return TRUE;\r
-}\r
-\r
-DWinding* DPlane::BaseWindingForPlane()\r
-{\r
-       int             i, x;\r
-       vec_t   max, v;\r
-       vec3_t  org, vright, vup;\r
-       \r
-// find the major axis\r
-\r
-       max = -131072;\r
-       x = -1;\r
-       for (i=0 ; i<3; i++)\r
-       {\r
-               v = (float)fabs(normal[i]);\r
-               if (v > max)\r
-               {\r
-                       x = i;\r
-                       max = v;\r
-               }\r
-       }\r
-       if (x==-1)\r
-               Sys_Printf ("BaseWindingForPlane: no axis found");\r
-               \r
-       VectorCopy (vec3_origin, vup);  \r
-       switch (x)\r
-       {\r
-       case 0:\r
-       case 1:\r
-               vup[2] = 1;\r
-               break;          \r
-       case 2:\r
-               vup[0] = 1;\r
-               break;          \r
-       }\r
-\r
-       v = DotProduct (vup, normal);\r
-       VectorMA (vup, -v, normal, vup);\r
-       VectorNormalize (vup, vup);\r
-               \r
-       VectorScale (normal, _d, org);\r
-       \r
-       CrossProduct (vup, normal, vright);\r
-       \r
-       VectorScale (vup, 131072, vup);\r
-       VectorScale (vright, 131072, vright);\r
-\r
-// project a really big        axis aligned box onto the plane\r
-       DWinding* w = new DWinding;\r
-       w->AllocWinding(4);\r
-       \r
-       VectorSubtract (org, vright, w->p[0]);\r
-       VectorAdd (w->p[0], vup, w->p[0]);\r
-       \r
-       VectorAdd (org, vright, w->p[1]);\r
-       VectorAdd (w->p[1], vup, w->p[1]);\r
-       \r
-       VectorAdd (org, vright, w->p[2]);\r
-       VectorSubtract (w->p[2], vup, w->p[2]);\r
-       \r
-       VectorSubtract (org, vright, w->p[3]);\r
-       VectorSubtract (w->p[3], vup, w->p[3]);\r
-               \r
-       return w;       \r
-}\r
-\r
-void DPlane::Rebuild()\r
-{\r
-       vec3_t v1, v2;\r
-       VectorSubtract(points[0], points[1], v1);\r
-       VectorSubtract(points[2], points[1], v2);\r
-       CrossProduct(v1, v2, normal);\r
-\r
-       if(VectorNormalize(normal, normal) == 0)        // normalizes and returns length\r
-               Sys_ERROR("DPlane::Rebuild: Bad Normal.\n");\r
-\r
-       _d = (normal[0]*points[0][0]) + (normal[1]*points[0][1]) + (normal[2]*points[0][2]);\r
-\r
-       VectorCopy(points[0], texInfo.m_v1);\r
-       VectorCopy(points[1], texInfo.m_v2);\r
-       VectorCopy(points[2], texInfo.m_v3);\r
-}\r
-\r
-bool DPlane::AddToBrush_t(brush_t *brush)\r
-{\r
-       if(m_bChkOk || !strcmp(texInfo.m_TextureName, "textures/common/caulk"))\r
-       {\r
-               g_FuncTable.m_pfnAddFaceData(brush, &texInfo);\r
-               return FALSE;\r
-       }\r
-\r
-       strcpy(texInfo.m_TextureName, "textures/common/caulk");\r
-       g_FuncTable.m_pfnAddFaceData(brush, &texInfo);\r
-       return TRUE;\r
-}\r
-\r
-void DPlane::ScaleTexture()\r
-{ }\r
-\r
-DPlane::DPlane(vec3_t va, vec3_t vb, vec3_t vc, const char* textureName, bool bDetail)\r
-{\r
-       vec3_t v1, v2;\r
-       VectorSubtract(va, vb, v1);\r
-       VectorSubtract(vc, vb, v2);\r
-       CrossProduct(v1, v2, normal);\r
-\r
-       if(VectorNormalize(normal, normal) == 0)        // normalizes and returns length\r
-               Sys_ERROR("DPlane::DPlane: Bad Normal.\n");\r
-\r
-       _d = (normal[0]*va[0]) + (normal[1]*va[1]) + (normal[2]*va[2]);\r
-\r
-       VectorCopy(va, points[0]);\r
-       VectorCopy(vb, points[1]);\r
-       VectorCopy(vc, points[2]);\r
-\r
-       m_bChkOk = TRUE;\r
-\r
-       FillDefaultTexture(&texInfo, points[0], points[1], points[2], textureName);\r
-       if(bDetail)\r
-               texInfo.m_nContents |= FACE_DETAIL;\r
-}\r
+/*
+   BobToolz plugin for GtkRadiant
+   Copyright (C) 2001 Gordon Biggans
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+// DPlane.cpp: implementation of the DPlane class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "DPlane.h"
+
+#include <list>
+
+#include "DPoint.h"
+#include "DWinding.h"
+
+#include "str.h"
+#include "misc.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+DPlane::DPlane(const vec3_t va, const vec3_t vb, const vec3_t vc, const _QERFaceData *texData)
+{
+    MakeNormal(va, vb, vc, normal);
+    if (VectorNormalize(normal, normal) == 0) {  // normalizes and returns length
+        globalErrorStream() << "DPlane::DPlane: Bad Normal.\n";
+    }
+
+    _d = (normal[0] * va[0]) + (normal[1] * va[1]) + (normal[2] * va[2]);
+
+    VectorCopy(va, points[0]);
+    VectorCopy(vb, points[1]);
+    VectorCopy(vc, points[2]);
+
+    m_bChkOk = true;
+
+    if (texData) {
+        memcpy(&texInfo, texData, sizeof(_QERFaceData));
+    } else {
+        FillDefaultTexture(&texInfo, points[0], points[1], points[2], "textures/common/caulk");
+    }
+}
+
+DPlane::~DPlane()
+{
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// Implementation
+//////////////////////////////////////////////////////////////////////
+
+vec_t DPlane::DistanceToPoint(vec3_t pnt)
+{
+    vec3_t tmp;
+    VectorSubtract(pnt, points[0], tmp);
+    return DotProduct(tmp, normal);
+}
+
+bool DPlane::PlaneIntersection(DPlane *pl1, DPlane *pl2, vec3_t out)
+{
+    float a1, a2, a3;
+    float b1, b2, b3;
+    float c1, c2, c3;
+
+    a1 = normal[0];
+    a2 = normal[1];
+    a3 = normal[2];
+    b1 = pl1->normal[0];
+    b2 = pl1->normal[1];
+    b3 = pl1->normal[2];
+    c1 = pl2->normal[0];
+    c2 = pl2->normal[1];
+    c3 = pl2->normal[2];
+
+    float d = Determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
+
+    if (d == 0) {
+        return false;
+    }
+
+    float v1 = _d;
+    float v2 = pl1->_d;
+    float v3 = pl2->_d;
+
+    float d1 = Determinant3x3(v1, a2, a3, v2, b2, b3, v3, c2, c3);
+    float d2 = Determinant3x3(a1, v1, a3, b1, v2, b3, c1, v3, c3);
+    float d3 = Determinant3x3(a1, a2, v1, b1, b2, v2, c1, c2, v3);
+
+    out[0] = d1 / d;
+    out[1] = d2 / d;
+    out[2] = d3 / d;
+
+    return true;
+}
+
+bool DPlane::IsRedundant(std::list<DPoint *> &pointList)
+{
+    int cnt = 0;
+
+    //std::list<DPoint *>::const_iterator point=pointList.begin();
+    for (std::list<DPoint *>::const_iterator point = pointList.begin(); point != pointList.end(); point++) {
+        if (fabs(DistanceToPoint((*point)->_pnt)) < MAX_ROUND_ERROR) {
+            cnt++;
+        }
+
+        if (cnt == 3) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool DPlane::operator==(DPlane &other)
+{
+    vec3_t chk;
+    VectorSubtract(other.normal, normal, chk);
+    if (fabs(VectorLength(chk)) > MAX_ROUND_ERROR) {
+        return false;
+    }
+
+    if (fabs(other._d - _d) > MAX_ROUND_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+bool DPlane::operator!=(DPlane &other)
+{
+    vec3_t chk;
+    VectorAdd(other.normal, normal, chk);
+    if (fabs(VectorLength(chk)) > MAX_ROUND_ERROR) {
+        return false;
+    }
+
+    return true;
+}
+
+DWinding *DPlane::BaseWindingForPlane()
+{
+    int i, x;
+    vec_t max, v;
+    vec3_t org, vright, vup;
+
+// find the major axis
+
+    max = -131072;
+    x = -1;
+    for (i = 0; i < 3; i++) {
+        v = (float) fabs(normal[i]);
+        if (v > max) {
+            x = i;
+            max = v;
+        }
+    }
+    if (x == -1) {
+        globalOutputStream() << "BaseWindingForPlane: no axis found";
+    }
+
+    VectorCopy(vec3_origin, vup);
+    switch (x) {
+        case 0:
+        case 1:
+            vup[2] = 1;
+            break;
+        case 2:
+            vup[0] = 1;
+            break;
+    }
+
+    v = DotProduct(vup, normal);
+    VectorMA(vup, -v, normal, vup);
+    VectorNormalize(vup, vup);
+
+    VectorScale(normal, _d, org);
+
+    CrossProduct(vup, normal, vright);
+
+    VectorScale(vup, 131072, vup);
+    VectorScale(vright, 131072, vright);
+
+// project a really big        axis aligned box onto the plane
+    DWinding *w = new DWinding;
+    w->AllocWinding(4);
+
+    VectorSubtract(org, vright, w->p[0]);
+    VectorAdd(w->p[0], vup, w->p[0]);
+
+    VectorAdd(org, vright, w->p[1]);
+    VectorAdd(w->p[1], vup, w->p[1]);
+
+    VectorAdd(org, vright, w->p[2]);
+    VectorSubtract(w->p[2], vup, w->p[2]);
+
+    VectorSubtract(org, vright, w->p[3]);
+    VectorSubtract(w->p[3], vup, w->p[3]);
+
+    return w;
+}
+
+void DPlane::Rebuild()
+{
+    vec3_t v1, v2;
+    VectorSubtract(points[0], points[1], v1);
+    VectorSubtract(points[2], points[1], v2);
+    CrossProduct(v1, v2, normal);
+
+    if (VectorNormalize(normal, normal) == 0) {  // normalizes and returns length
+        globalErrorStream() << "DPlane::Rebuild: Bad Normal.\n";
+    }
+
+    _d = (normal[0] * points[0][0]) + (normal[1] * points[0][1]) + (normal[2] * points[0][2]);
+
+    VectorCopy(points[0], texInfo.m_p0);
+    VectorCopy(points[1], texInfo.m_p1);
+    VectorCopy(points[2], texInfo.m_p2);
+}
+
+bool DPlane::AddToBrush(scene::Node &brush)
+{
+    bool changed = false;
+    if (!(m_bChkOk || !strcmp(m_shader.c_str(), "textures/common/caulk"))) {
+        m_shader = "textures/common/caulk";
+        changed = true;
+    }
+
+    _QERFaceData faceData;
+    faceData.m_p0 = vector3_from_array(points[0]);
+    faceData.m_p1 = vector3_from_array(points[1]);
+    faceData.m_p2 = vector3_from_array(points[2]);
+    faceData.m_texdef = texInfo.m_texdef;
+    faceData.m_shader = m_shader.c_str();
+    GlobalBrushCreator().Brush_addFace(brush, faceData);
+
+    return changed;
+}
+
+void DPlane::ScaleTexture()
+{}
+
+DPlane::DPlane(const vec3_t va, const vec3_t vb, const vec3_t vc, const char *textureName, bool bDetail)
+{
+    vec3_t v1, v2;
+    VectorSubtract(va, vb, v1);
+    VectorSubtract(vc, vb, v2);
+    CrossProduct(v1, v2, normal);
+
+    if (VectorNormalize(normal, normal) == 0) {  // normalizes and returns length
+        globalErrorStream() << "DPlane::DPlane: Bad Normal.\n";
+    }
+
+    _d = (normal[0] * va[0]) + (normal[1] * va[1]) + (normal[2] * va[2]);
+
+    VectorCopy(va, points[0]);
+    VectorCopy(vb, points[1]);
+    VectorCopy(vc, points[2]);
+
+    m_bChkOk = true;
+
+    FillDefaultTexture(&texInfo, points[0], points[1], points[2], textureName);
+    if (bDetail) {
+        texInfo.contents |= FACE_DETAIL;
+    }
+}