Add polygon triangulation, by cheating. I'm using the gl tesselator
for that, and storing the triangles instead of rendering them immediately. Not sure if that's smart; in theory could change from implementation to implementation, but the results look much better than I would get myself. [git-p4: depot-paths = "//depot/solvespace/": change = 1733]solver
parent
e80328279e
commit
7c4d305895
1
Makefile
1
Makefile
|
@ -22,6 +22,7 @@ SSOBJS = $(OBJDIR)\solvespace.obj \
|
||||||
$(OBJDIR)\file.obj \
|
$(OBJDIR)\file.obj \
|
||||||
$(OBJDIR)\system.obj \
|
$(OBJDIR)\system.obj \
|
||||||
$(OBJDIR)\polygon.obj \
|
$(OBJDIR)\polygon.obj \
|
||||||
|
$(OBJDIR)\mesh.obj \
|
||||||
|
|
||||||
|
|
||||||
LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib opengl32.lib glu32.lib
|
LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib opengl32.lib glu32.lib
|
||||||
|
|
|
@ -527,10 +527,7 @@ void Entity::LineDrawOrGetDistance(Vector a, Vector b) {
|
||||||
void Entity::LineDrawOrGetDistanceOrEdge(Vector a, Vector b) {
|
void Entity::LineDrawOrGetDistanceOrEdge(Vector a, Vector b) {
|
||||||
LineDrawOrGetDistance(a, b);
|
LineDrawOrGetDistance(a, b);
|
||||||
if(dogd.edges && !construction) {
|
if(dogd.edges && !construction) {
|
||||||
SEdge edge;
|
dogd.edges->AddEdge(a, b);
|
||||||
edge.tag = 0;
|
|
||||||
edge.a = a; edge.b = b;
|
|
||||||
dogd.edges->l.Add(&edge);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
55
glhelper.cpp
55
glhelper.cpp
|
@ -111,10 +111,23 @@ void glxColor4d(double r, double g, double b, double a)
|
||||||
if(!ColorLocked) glColor4d(r, g, b, a);
|
if(!ColorLocked) glColor4d(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __stdcall Vertex(Vector *p) {
|
static void GLX_CALLBACK Vertex(Vector *p) {
|
||||||
glxVertex3v(*p);
|
glxVertex3v(*p);
|
||||||
}
|
}
|
||||||
static void __stdcall Combine(double coords[3], void *vertexData[4],
|
|
||||||
|
void glxFillPolygon(SPolygon *p)
|
||||||
|
{
|
||||||
|
GLUtesselator *gt = gluNewTess();
|
||||||
|
gluTessCallback(gt, GLU_TESS_BEGIN, (glxCallbackFptr *)glBegin);
|
||||||
|
gluTessCallback(gt, GLU_TESS_END, (glxCallbackFptr *)glEnd);
|
||||||
|
gluTessCallback(gt, GLU_TESS_VERTEX, (glxCallbackFptr *)Vertex);
|
||||||
|
|
||||||
|
glxTesselatePolygon(gt, p);
|
||||||
|
|
||||||
|
gluDeleteTess(gt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GLX_CALLBACK Combine(double coords[3], void *vertexData[4],
|
||||||
float weight[4], void **outData)
|
float weight[4], void **outData)
|
||||||
{
|
{
|
||||||
Vector *n = (Vector *)AllocTemporary(sizeof(Vector));
|
Vector *n = (Vector *)AllocTemporary(sizeof(Vector));
|
||||||
|
@ -124,16 +137,11 @@ static void __stdcall Combine(double coords[3], void *vertexData[4],
|
||||||
|
|
||||||
*outData = n;
|
*outData = n;
|
||||||
}
|
}
|
||||||
void glxFillPolygon(SPolygon *p)
|
void glxTesselatePolygon(GLUtesselator *gt, SPolygon *p)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
GLUtesselator *gt = gluNewTess();
|
gluTessCallback(gt, GLU_TESS_COMBINE, (glxCallbackFptr *)Combine);
|
||||||
typedef void __stdcall cf(void);
|
|
||||||
gluTessCallback(gt, GLU_TESS_BEGIN, (cf *)glBegin);
|
|
||||||
gluTessCallback(gt, GLU_TESS_END, (cf *)glEnd);
|
|
||||||
gluTessCallback(gt, GLU_TESS_VERTEX, (cf *)Vertex);
|
|
||||||
gluTessCallback(gt, GLU_TESS_COMBINE, (cf *)Combine);
|
|
||||||
gluTessProperty(gt, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
|
gluTessProperty(gt, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
|
||||||
|
|
||||||
Vector normal = p->normal;
|
Vector normal = p->normal;
|
||||||
|
@ -155,7 +163,6 @@ void glxFillPolygon(SPolygon *p)
|
||||||
gluTessEndContour(gt);
|
gluTessEndContour(gt);
|
||||||
}
|
}
|
||||||
gluTessEndPolygon(gt);
|
gluTessEndPolygon(gt);
|
||||||
gluDeleteTess(gt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void glxDebugPolygon(SPolygon *p)
|
void glxDebugPolygon(SPolygon *p)
|
||||||
|
@ -196,7 +203,7 @@ void glxDebugEdgeList(SEdgeList *el)
|
||||||
if(se->tag) continue;
|
if(se->tag) continue;
|
||||||
Vector a = se->a, b = se->b;
|
Vector a = se->a, b = se->b;
|
||||||
|
|
||||||
glxLockColorTo(0, 1, 0);
|
glxLockColorTo(0, 1, 1);
|
||||||
Vector d = (a.Minus(b)).WithMagnitude(-0);
|
Vector d = (a.Minus(b)).WithMagnitude(-0);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glxVertex3v(a.Plus(d));
|
glxVertex3v(a.Plus(d));
|
||||||
|
@ -210,6 +217,32 @@ void glxDebugEdgeList(SEdgeList *el)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void glxDebugMesh(SMesh *m)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
glLineWidth(2);
|
||||||
|
glPointSize(7);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glxUnlockColor();
|
||||||
|
for(i = 0; i < m->l.n; i++) {
|
||||||
|
STriangle *t = &(m->l.elem[i]);
|
||||||
|
if(t->tag) continue;
|
||||||
|
|
||||||
|
glxColor4d(0, 1, 0, 0.3);
|
||||||
|
glBegin(GL_LINE_LOOP);
|
||||||
|
glxVertex3v(t->a);
|
||||||
|
glxVertex3v(t->b);
|
||||||
|
glxVertex3v(t->c);
|
||||||
|
glEnd();
|
||||||
|
glxColor4d(0, 0, 1, 0.4);
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
glxVertex3v(t->a);
|
||||||
|
glxVertex3v(t->b);
|
||||||
|
glxVertex3v(t->c);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void glxMarkPolygonNormal(SPolygon *p)
|
void glxMarkPolygonNormal(SPolygon *p)
|
||||||
{
|
{
|
||||||
Vector tail = Vector::MakeFrom(0, 0, 0);
|
Vector tail = Vector::MakeFrom(0, 0, 0);
|
||||||
|
|
|
@ -1181,10 +1181,11 @@ void GraphicsWindow::Paint(int w, int h) {
|
||||||
selection[i].Draw();
|
selection[i].Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SS.group.n >= 5) {
|
if(SS.group.n >= 2) {
|
||||||
if(1) {
|
SMesh m; ZERO(&m);
|
||||||
//XXX
|
(SS.group.elem[1].poly).TriangulateInto(&m);
|
||||||
}
|
glxDebugMesh(&m);
|
||||||
|
m.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
205
polygon.cpp
205
polygon.cpp
|
@ -1,5 +1,16 @@
|
||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
|
|
||||||
|
void SEdgeList::Clear(void) {
|
||||||
|
l.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SEdgeList::AddEdge(Vector a, Vector b) {
|
||||||
|
SEdge e; ZERO(&e);
|
||||||
|
e.a = a;
|
||||||
|
e.b = b;
|
||||||
|
l.Add(&e);
|
||||||
|
}
|
||||||
|
|
||||||
bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt) {
|
bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt) {
|
||||||
dest->Clear();
|
dest->Clear();
|
||||||
|
|
||||||
|
@ -52,79 +63,6 @@ bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPolygon::Clear(void) {
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < l.n; i++) {
|
|
||||||
(l.elem[i]).l.Clear();
|
|
||||||
}
|
|
||||||
l.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPolygon::AddEmptyContour(void) {
|
|
||||||
SContour c;
|
|
||||||
memset(&c, 0, sizeof(c));
|
|
||||||
l.Add(&c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPolygon::AddPoint(Vector p) {
|
|
||||||
if(l.n < 1) oops();
|
|
||||||
|
|
||||||
SPoint sp;
|
|
||||||
sp.tag = 0;
|
|
||||||
sp.p = p;
|
|
||||||
|
|
||||||
// Add to the last contour in the list
|
|
||||||
(l.elem[l.n-1]).l.Add(&sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPolygon::MakeEdgesInto(SEdgeList *el) {
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < l.n; i++) {
|
|
||||||
(l.elem[i]).MakeEdgesInto(el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector SPolygon::ComputeNormal(void) {
|
|
||||||
if(l.n < 1) return Vector::MakeFrom(0, 0, 0);
|
|
||||||
return (l.elem[0]).ComputeNormal();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SPolygon::ContainsPoint(Vector p) {
|
|
||||||
bool inside = false;
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < l.n; i++) {
|
|
||||||
SContour *sc = &(l.elem[i]);
|
|
||||||
if(sc->ContainsPointProjdToNormal(normal, p)) {
|
|
||||||
inside = !inside;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPolygon::FixContourDirections(void) {
|
|
||||||
// Outside curve looks counterclockwise, projected against our normal.
|
|
||||||
int i, j;
|
|
||||||
for(i = 0; i < l.n; i++) {
|
|
||||||
SContour *sc = &(l.elem[i]);
|
|
||||||
if(sc->l.n < 1) continue;
|
|
||||||
Vector pt = (sc->l.elem[0]).p;
|
|
||||||
|
|
||||||
bool outer = true;
|
|
||||||
for(j = 0; j < l.n; j++) {
|
|
||||||
if(i == j) continue;
|
|
||||||
SContour *sct = &(l.elem[j]);
|
|
||||||
if(sct->ContainsPointProjdToNormal(normal, pt)) {
|
|
||||||
outer = !outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool clockwise = sc->IsClockwiseProjdToNormal(normal);
|
|
||||||
if(clockwise && outer || (!clockwise && !outer)) {
|
|
||||||
sc->Reverse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SContour::MakeEdgesInto(SEdgeList *el) {
|
void SContour::MakeEdgesInto(SEdgeList *el) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < (l.n-1); i++) {
|
for(i = 0; i < (l.n-1); i++) {
|
||||||
|
@ -208,3 +146,124 @@ void SContour::Reverse(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SPolygon::Clear(void) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < l.n; i++) {
|
||||||
|
(l.elem[i]).l.Clear();
|
||||||
|
}
|
||||||
|
l.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPolygon::AddEmptyContour(void) {
|
||||||
|
SContour c;
|
||||||
|
memset(&c, 0, sizeof(c));
|
||||||
|
l.Add(&c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPolygon::AddPoint(Vector p) {
|
||||||
|
if(l.n < 1) oops();
|
||||||
|
|
||||||
|
SPoint sp;
|
||||||
|
sp.tag = 0;
|
||||||
|
sp.p = p;
|
||||||
|
|
||||||
|
// Add to the last contour in the list
|
||||||
|
(l.elem[l.n-1]).l.Add(&sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPolygon::MakeEdgesInto(SEdgeList *el) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < l.n; i++) {
|
||||||
|
(l.elem[i]).MakeEdgesInto(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector SPolygon::ComputeNormal(void) {
|
||||||
|
if(l.n < 1) return Vector::MakeFrom(0, 0, 0);
|
||||||
|
return (l.elem[0]).ComputeNormal();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SPolygon::ContainsPoint(Vector p) {
|
||||||
|
bool inside = false;
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < l.n; i++) {
|
||||||
|
SContour *sc = &(l.elem[i]);
|
||||||
|
if(sc->ContainsPointProjdToNormal(normal, p)) {
|
||||||
|
inside = !inside;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPolygon::FixContourDirections(void) {
|
||||||
|
// Outside curve looks counterclockwise, projected against our normal.
|
||||||
|
int i, j;
|
||||||
|
for(i = 0; i < l.n; i++) {
|
||||||
|
SContour *sc = &(l.elem[i]);
|
||||||
|
if(sc->l.n < 1) continue;
|
||||||
|
Vector pt = (sc->l.elem[0]).p;
|
||||||
|
|
||||||
|
bool outer = true;
|
||||||
|
for(j = 0; j < l.n; j++) {
|
||||||
|
if(i == j) continue;
|
||||||
|
SContour *sct = &(l.elem[j]);
|
||||||
|
if(sct->ContainsPointProjdToNormal(normal, pt)) {
|
||||||
|
outer = !outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool clockwise = sc->IsClockwiseProjdToNormal(normal);
|
||||||
|
if(clockwise && outer || (!clockwise && !outer)) {
|
||||||
|
sc->Reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TriMode, TriVertexCount;
|
||||||
|
static Vector Tri1, TriNMinus1, TriNMinus2;
|
||||||
|
static SMesh *TriMesh;
|
||||||
|
static void GLX_CALLBACK TriBegin(int mode)
|
||||||
|
{
|
||||||
|
TriMode = mode;
|
||||||
|
TriVertexCount = 0;
|
||||||
|
}
|
||||||
|
static void GLX_CALLBACK TriEnd(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static void GLX_CALLBACK TriVertex(Vector *triN)
|
||||||
|
{
|
||||||
|
if(TriVertexCount == 0) {
|
||||||
|
Tri1 = *triN;
|
||||||
|
}
|
||||||
|
if(TriMode == GL_TRIANGLES) {
|
||||||
|
if((TriVertexCount % 3) == 2) {
|
||||||
|
TriMesh->AddTriangle(TriNMinus2, TriNMinus1, *triN);
|
||||||
|
}
|
||||||
|
} else if(TriMode == GL_TRIANGLE_FAN) {
|
||||||
|
if(TriVertexCount >= 2) {
|
||||||
|
TriMesh->AddTriangle(Tri1, TriNMinus1, *triN);
|
||||||
|
}
|
||||||
|
} else if(TriMode == GL_TRIANGLE_STRIP) {
|
||||||
|
if(TriVertexCount >= 2) {
|
||||||
|
TriMesh->AddTriangle(TriNMinus2, TriNMinus1, *triN);
|
||||||
|
}
|
||||||
|
} else oops();
|
||||||
|
|
||||||
|
TriNMinus2 = TriNMinus1;
|
||||||
|
TriNMinus1 = *triN;
|
||||||
|
TriVertexCount++;
|
||||||
|
}
|
||||||
|
void SPolygon::TriangulateInto(SMesh *m) {
|
||||||
|
TriMesh = m;
|
||||||
|
|
||||||
|
GLUtesselator *gt = gluNewTess();
|
||||||
|
gluTessCallback(gt, GLU_TESS_BEGIN, (glxCallbackFptr *)TriBegin);
|
||||||
|
gluTessCallback(gt, GLU_TESS_END, (glxCallbackFptr *)TriEnd);
|
||||||
|
gluTessCallback(gt, GLU_TESS_VERTEX, (glxCallbackFptr *)TriVertex);
|
||||||
|
|
||||||
|
glxTesselatePolygon(gt, this);
|
||||||
|
|
||||||
|
gluDeleteTess(gt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
23
polygon.h
23
polygon.h
|
@ -3,6 +3,7 @@
|
||||||
#define __POLYGON_H
|
#define __POLYGON_H
|
||||||
|
|
||||||
class SPolygon;
|
class SPolygon;
|
||||||
|
class SMesh;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class SList {
|
class SList {
|
||||||
|
@ -43,12 +44,9 @@ class SEdgeList {
|
||||||
public:
|
public:
|
||||||
SList<SEdge> l;
|
SList<SEdge> l;
|
||||||
|
|
||||||
|
void Clear(void);
|
||||||
|
void AddEdge(Vector a, Vector b);
|
||||||
bool AssemblePolygon(SPolygon *dest, SEdge *errorAt);
|
bool AssemblePolygon(SPolygon *dest, SEdge *errorAt);
|
||||||
void CopyBreaking(SEdgeList *dest);
|
|
||||||
static const int UNION = 0, DIFF = 1, INTERSECT = 2;
|
|
||||||
bool BooleanOp(int op, bool inA, bool inB);
|
|
||||||
void CullForBoolean(int op, SPolygon *a, SPolygon *b);
|
|
||||||
void CullDuplicates(void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SPoint {
|
class SPoint {
|
||||||
|
@ -66,8 +64,6 @@ public:
|
||||||
Vector ComputeNormal(void);
|
Vector ComputeNormal(void);
|
||||||
bool IsClockwiseProjdToNormal(Vector n);
|
bool IsClockwiseProjdToNormal(Vector n);
|
||||||
bool ContainsPointProjdToNormal(Vector n, Vector p);
|
bool ContainsPointProjdToNormal(Vector n, Vector p);
|
||||||
void IntersectAgainstPlane(double *inter, int *inters,
|
|
||||||
Vector u, Vector v, double vp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SPolygon {
|
class SPolygon {
|
||||||
|
@ -81,20 +77,24 @@ public:
|
||||||
bool ContainsPoint(Vector p);
|
bool ContainsPoint(Vector p);
|
||||||
void MakeEdgesInto(SEdgeList *el);
|
void MakeEdgesInto(SEdgeList *el);
|
||||||
void FixContourDirections(void);
|
void FixContourDirections(void);
|
||||||
|
void TriangulateInto(SMesh *m);
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class STriangle {
|
class STriangle {
|
||||||
public:
|
public:
|
||||||
|
int tag;
|
||||||
Vector a, b, c;
|
Vector a, b, c;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SBsp2 {
|
class SBsp2 {
|
||||||
|
public:
|
||||||
SEdge edge;
|
SEdge edge;
|
||||||
};
|
|
||||||
|
|
||||||
class SBsp1d {
|
SBsp2 *pos;
|
||||||
SEdge edge;
|
SBsp2 *neg;
|
||||||
|
|
||||||
|
SBsp2 *more;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SBsp3 {
|
class SBsp3 {
|
||||||
|
@ -112,6 +112,9 @@ public:
|
||||||
class SMesh {
|
class SMesh {
|
||||||
public:
|
public:
|
||||||
SList<STriangle> l;
|
SList<STriangle> l;
|
||||||
|
|
||||||
|
void Clear(void);
|
||||||
|
void AddTriangle(Vector a, Vector b, Vector c);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -418,7 +418,7 @@ void Group::MakePolygons(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the source polygon to extrude, and break it down to edges
|
// Get the source polygon to extrude, and break it down to edges
|
||||||
edges.l.Clear();
|
edges.Clear();
|
||||||
Group *src = SS.GetGroup(opA);
|
Group *src = SS.GetGroup(opA);
|
||||||
|
|
||||||
(src->poly).MakeEdgesInto(&edges);
|
(src->poly).MakeEdgesInto(&edges);
|
||||||
|
@ -440,7 +440,7 @@ void Group::MakePolygons(void) {
|
||||||
np.FixContourDirections();
|
np.FixContourDirections();
|
||||||
|
|
||||||
// Regenerate the edges, with the contour directions fixed up.
|
// Regenerate the edges, with the contour directions fixed up.
|
||||||
edges.l.Clear();
|
edges.Clear();
|
||||||
np.MakeEdgesInto(&edges);
|
np.MakeEdgesInto(&edges);
|
||||||
|
|
||||||
// The sides
|
// The sides
|
||||||
|
@ -465,7 +465,7 @@ void Group::MakePolygons(void) {
|
||||||
if(!edges.AssemblePolygon(&np, NULL)) oops();
|
if(!edges.AssemblePolygon(&np, NULL)) oops();
|
||||||
np.normal = n.ScaledBy(-1);
|
np.normal = n.ScaledBy(-1);
|
||||||
}
|
}
|
||||||
edges.l.Clear();
|
edges.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::Draw(void) {
|
void Group::Draw(void) {
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
|
|
||||||
#define SWAP(T, a, b) do { T temp = (a); (a) = (b); (b) = temp; } while(0)
|
#define SWAP(T, a, b) do { T temp = (a); (a) = (b); (b) = temp; } while(0)
|
||||||
#define ZERO(v) memset((v), 0, sizeof(*(v)))
|
#define ZERO(v) memset((v), 0, sizeof(*(v)))
|
||||||
|
#define CO(v) (v).x, (v).y, (v).z
|
||||||
|
|
||||||
|
#define LENGTH_EPS (0.0001)
|
||||||
|
|
||||||
#define isforname(c) (isalnum(c) || (c) == '_' || (c) == '-' || (c) == '#')
|
#define isforname(c) (isalnum(c) || (c) == '_' || (c) == '-' || (c) == '#')
|
||||||
|
|
||||||
|
@ -70,9 +73,13 @@ void vl(void); // debug function to validate
|
||||||
|
|
||||||
// Utility functions that are provided in the platform-independent code.
|
// Utility functions that are provided in the platform-independent code.
|
||||||
void glxVertex3v(Vector u);
|
void glxVertex3v(Vector u);
|
||||||
|
#define GLX_CALLBACK __stdcall
|
||||||
|
typedef void GLX_CALLBACK glxCallbackFptr(void);
|
||||||
|
void glxTesselatePolygon(GLUtesselator *gt, SPolygon *p);
|
||||||
void glxFillPolygon(SPolygon *p);
|
void glxFillPolygon(SPolygon *p);
|
||||||
void glxDebugPolygon(SPolygon *p);
|
void glxDebugPolygon(SPolygon *p);
|
||||||
void glxDebugEdgeList(SEdgeList *l);
|
void glxDebugEdgeList(SEdgeList *l);
|
||||||
|
void glxDebugMesh(SMesh *m);
|
||||||
void glxMarkPolygonNormal(SPolygon *p);
|
void glxMarkPolygonNormal(SPolygon *p);
|
||||||
void glxWriteText(char *str);
|
void glxWriteText(char *str);
|
||||||
void glxWriteTextRefCenter(char *str);
|
void glxWriteTextRefCenter(char *str);
|
||||||
|
|
7
util.cpp
7
util.cpp
|
@ -178,10 +178,9 @@ Vector Vector::MakeFrom(double x, double y, double z) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vector::Equals(Vector v) {
|
bool Vector::Equals(Vector v) {
|
||||||
double tol = 0.00001;
|
if(fabs(x - v.x) > LENGTH_EPS) return false;
|
||||||
if(fabs(x - v.x) > tol) return false;
|
if(fabs(y - v.y) > LENGTH_EPS) return false;
|
||||||
if(fabs(y - v.y) > tol) return false;
|
if(fabs(z - v.z) > LENGTH_EPS) return false;
|
||||||
if(fabs(z - v.z) > tol) return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue