mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-12-15 06:41:11 +00:00
265 lines
6 KiB
C++
265 lines
6 KiB
C++
|
/*
|
||
|
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 "StdAfx.h"
|
||
|
|
||
|
#include "gtkr_list.h"
|
||
|
|
||
|
#include "DPoint.h"
|
||
|
#include "DPlane.h"
|
||
|
#include "DWinding.h"
|
||
|
|
||
|
#include "str.h"
|
||
|
#include "misc.h"
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Construction/Destruction
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
DPlane::DPlane(vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData* texData)
|
||
|
{
|
||
|
MakeNormal( va, vb, vc, normal );
|
||
|
if(VectorNormalize(normal, normal) == 0) // normalizes and returns length
|
||
|
Sys_ERROR("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(list<DPoint*>& pointList)
|
||
|
{
|
||
|
int cnt = 0;
|
||
|
|
||
|
//list<DPoint *>::const_iterator point=pointList.begin();
|
||
|
for(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)
|
||
|
Sys_Printf ("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
|
||
|
Sys_ERROR("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(Brush *brush)
|
||
|
{
|
||
|
#if 0
|
||
|
if(m_bChkOk || !strcmp(texInfo.m_TextureName, "textures/common/caulk"))
|
||
|
{
|
||
|
brush->addPlane(m_p0, m_p1, m_p2, m_texdef, false);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
strcpy(texInfo.m_TextureName, "textures/common/caulk");
|
||
|
brush->addPlane(m_p0, m_p1, m_p2, m_texdef, false);
|
||
|
#endif
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void DPlane::ScaleTexture()
|
||
|
{ }
|
||
|
|
||
|
DPlane::DPlane(vec3_t va, vec3_t vb, 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
|
||
|
Sys_ERROR("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.m_texdef.contents |= FACE_DETAIL;
|
||
|
}
|