Add perspective, by a user-specified factor. So I have to apply
that perspective in the gl matrices, and also everywhere that I check mouse pointer positions against the model, and for the zoom to fit. [git-p4: depot-paths = "//depot/solvespace/": change = 1796]
This commit is contained in:
parent
b5c87291ea
commit
e67ea9ca0f
25
draw.cpp
25
draw.cpp
@ -835,14 +835,25 @@ void GraphicsWindow::Paint(int w, int h) {
|
|||||||
|
|
||||||
glScaled(scale*2.0/w, scale*2.0/h, scale*1.0/30000);
|
glScaled(scale*2.0/w, scale*2.0/h, scale*1.0/30000);
|
||||||
|
|
||||||
double tx = projRight.Dot(offset);
|
|
||||||
double ty = projUp.Dot(offset);
|
|
||||||
Vector n = projUp.Cross(projRight);
|
|
||||||
double tz = n.Dot(offset);
|
|
||||||
double mat[16];
|
double mat[16];
|
||||||
MakeMatrix(mat, projRight.x, projRight.y, projRight.z, tx,
|
// Last thing before display is to apply the perspective
|
||||||
projUp.x, projUp.y, projUp.z, ty,
|
double clp = SS.cameraTangent*scale;
|
||||||
n.x, n.y, n.z, tz,
|
MakeMatrix(mat, 1, 0, 0, 0,
|
||||||
|
0, 1, 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 0, clp, 1);
|
||||||
|
glMultMatrixd(mat);
|
||||||
|
// Before that, we apply the rotation
|
||||||
|
Vector n = projUp.Cross(projRight);
|
||||||
|
MakeMatrix(mat, projRight.x, projRight.y, projRight.z, 0,
|
||||||
|
projUp.x, projUp.y, projUp.z, 0,
|
||||||
|
n.x, n.y, n.z, 0,
|
||||||
|
0, 0, 0, 1);
|
||||||
|
glMultMatrixd(mat);
|
||||||
|
// And before that, the translation
|
||||||
|
MakeMatrix(mat, 1, 0, 0, offset.x,
|
||||||
|
0, 1, 0, offset.y,
|
||||||
|
0, 0, 1, offset.z,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
glMultMatrixd(mat);
|
glMultMatrixd(mat);
|
||||||
|
|
||||||
|
@ -2,15 +2,13 @@
|
|||||||
|
|
||||||
void Entity::LineDrawOrGetDistance(Vector a, Vector b) {
|
void Entity::LineDrawOrGetDistance(Vector a, Vector b) {
|
||||||
if(dogd.drawing) {
|
if(dogd.drawing) {
|
||||||
// glPolygonOffset works only on polys, not lines, so do it myself
|
|
||||||
Vector adj = SS.GW.projRight.Cross(SS.GW.projUp);
|
|
||||||
// Draw lines from active group in front of those from previous
|
// Draw lines from active group in front of those from previous
|
||||||
int delta = (group.v == SS.GW.activeGroup.v) ? 10 : 5;
|
glxDepthRangeOffset((group.v == SS.GW.activeGroup.v) ? 4 : 2);
|
||||||
adj = adj.ScaledBy(delta/SS.GW.scale);
|
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glxVertex3v(a.Plus(adj));
|
glxVertex3v(a);
|
||||||
glxVertex3v(b.Plus(adj));
|
glxVertex3v(b);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
glxDepthRangeOffset(0);
|
||||||
} else {
|
} else {
|
||||||
Point2d ap = SS.GW.ProjectPoint(a);
|
Point2d ap = SS.GW.ProjectPoint(a);
|
||||||
Point2d bp = SS.GW.ProjectPoint(b);
|
Point2d bp = SS.GW.ProjectPoint(b);
|
||||||
@ -40,7 +38,7 @@ void Entity::DrawAll(void) {
|
|||||||
Vector r = SS.GW.projRight.ScaledBy(s);
|
Vector r = SS.GW.projRight.ScaledBy(s);
|
||||||
Vector d = SS.GW.projUp.ScaledBy(s);
|
Vector d = SS.GW.projUp.ScaledBy(s);
|
||||||
glxColor3d(0, 0.8, 0);
|
glxColor3d(0, 0.8, 0);
|
||||||
glPolygonOffset(-10, -10);
|
glxDepthRangeOffset(6);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
for(i = 0; i < SS.entity.n; i++) {
|
for(i = 0; i < SS.entity.n; i++) {
|
||||||
Entity *e = &(SS.entity.elem[i]);
|
Entity *e = &(SS.entity.elem[i]);
|
||||||
@ -56,7 +54,7 @@ void Entity::DrawAll(void) {
|
|||||||
glxVertex3v(v.Minus(r).Plus (d));
|
glxVertex3v(v.Minus(r).Plus (d));
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
glPolygonOffset(0, 0);
|
glxDepthRangeOffset(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glLineWidth(1.5);
|
glLineWidth(1.5);
|
||||||
@ -167,14 +165,14 @@ void Entity::DrawOrGetDistance(void) {
|
|||||||
Vector d = SS.GW.projUp.ScaledBy(s/SS.GW.scale);
|
Vector d = SS.GW.projUp.ScaledBy(s/SS.GW.scale);
|
||||||
|
|
||||||
glxColor3d(0, 0.8, 0);
|
glxColor3d(0, 0.8, 0);
|
||||||
glPolygonOffset(-10, -10);
|
glxDepthRangeOffset(6);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glxVertex3v(v.Plus (r).Plus (d));
|
glxVertex3v(v.Plus (r).Plus (d));
|
||||||
glxVertex3v(v.Plus (r).Minus(d));
|
glxVertex3v(v.Plus (r).Minus(d));
|
||||||
glxVertex3v(v.Minus(r).Minus(d));
|
glxVertex3v(v.Minus(r).Minus(d));
|
||||||
glxVertex3v(v.Minus(r).Plus (d));
|
glxVertex3v(v.Minus(r).Plus (d));
|
||||||
glEnd();
|
glEnd();
|
||||||
glPolygonOffset(0, 0);
|
glxDepthRangeOffset(0);
|
||||||
} else {
|
} else {
|
||||||
Point2d pp = SS.GW.ProjectPoint(v);
|
Point2d pp = SS.GW.ProjectPoint(v);
|
||||||
dogd.dmin = pp.DistanceTo(dogd.mp) - 6;
|
dogd.dmin = pp.DistanceTo(dogd.mp) - 6;
|
||||||
@ -214,10 +212,9 @@ void Entity::DrawOrGetDistance(void) {
|
|||||||
double s = SS.GW.scale;
|
double s = SS.GW.scale;
|
||||||
double h = 60 - SS.GW.height/2;
|
double h = 60 - SS.GW.height/2;
|
||||||
double w = 60 - SS.GW.width/2;
|
double w = 60 - SS.GW.width/2;
|
||||||
Vector gn = SS.GW.projRight.Cross(SS.GW.projUp);
|
|
||||||
tail = SS.GW.projRight.ScaledBy(w/s).Plus(
|
tail = SS.GW.projRight.ScaledBy(w/s).Plus(
|
||||||
SS.GW.projUp. ScaledBy(h/s)).Plus(
|
SS.GW.projUp. ScaledBy(h/s)).Minus(SS.GW.offset);
|
||||||
gn.ScaledBy(-4*w/s)).Minus(SS.GW.offset);
|
glxDepthRangeLockToFront(true);
|
||||||
glLineWidth(2);
|
glLineWidth(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +227,7 @@ void Entity::DrawOrGetDistance(void) {
|
|||||||
LineDrawOrGetDistance(tip,tip.Minus(v.RotatedAbout(axis, 0.6)));
|
LineDrawOrGetDistance(tip,tip.Minus(v.RotatedAbout(axis, 0.6)));
|
||||||
LineDrawOrGetDistance(tip,tip.Minus(v.RotatedAbout(axis,-0.6)));
|
LineDrawOrGetDistance(tip,tip.Minus(v.RotatedAbout(axis,-0.6)));
|
||||||
}
|
}
|
||||||
|
glxDepthRangeLockToFront(false);
|
||||||
glLineWidth(1.5);
|
glLineWidth(1.5);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
23
glhelper.cpp
23
glhelper.cpp
@ -4,6 +4,7 @@
|
|||||||
#include "font.table"
|
#include "font.table"
|
||||||
|
|
||||||
static bool ColorLocked;
|
static bool ColorLocked;
|
||||||
|
static bool DepthOffsetLocked;
|
||||||
|
|
||||||
#define FONT_SCALE (0.55)
|
#define FONT_SCALE (0.55)
|
||||||
double glxStrWidth(char *str) {
|
double glxStrWidth(char *str) {
|
||||||
@ -309,6 +310,7 @@ void glxDebugMesh(SMesh *m)
|
|||||||
int i;
|
int i;
|
||||||
glLineWidth(1);
|
glLineWidth(1);
|
||||||
glPointSize(7);
|
glPointSize(7);
|
||||||
|
glxDepthRangeOffset(1);
|
||||||
glxUnlockColor();
|
glxUnlockColor();
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
STriangle *t = &(m->l.elem[i]);
|
STriangle *t = &(m->l.elem[i]);
|
||||||
@ -321,9 +323,9 @@ void glxDebugMesh(SMesh *m)
|
|||||||
glxVertex3v(t->b);
|
glxVertex3v(t->b);
|
||||||
glxVertex3v(t->c);
|
glxVertex3v(t->c);
|
||||||
glEnd();
|
glEnd();
|
||||||
glPolygonOffset(0, 0);
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
}
|
}
|
||||||
|
glxDepthRangeOffset(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glxMarkPolygonNormal(SPolygon *p)
|
void glxMarkPolygonNormal(SPolygon *p)
|
||||||
@ -358,3 +360,22 @@ void glxMarkPolygonNormal(SPolygon *p)
|
|||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void glxDepthRangeOffset(int units) {
|
||||||
|
if(!DepthOffsetLocked) {
|
||||||
|
// The size of this step depends on the resolution of the Z buffer; for
|
||||||
|
// a 16-bit buffer, this should be fine.
|
||||||
|
double d = units/60000.0;
|
||||||
|
glDepthRange(0.1-d, 1-d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glxDepthRangeLockToFront(bool yes) {
|
||||||
|
if(yes) {
|
||||||
|
DepthOffsetLocked = true;
|
||||||
|
glDepthRange(0, 0);
|
||||||
|
} else {
|
||||||
|
DepthOffsetLocked = false;
|
||||||
|
glxDepthRangeOffset(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
101
graphicswin.cpp
101
graphicswin.cpp
@ -125,12 +125,38 @@ void GraphicsWindow::NormalizeProjectionVectors(void) {
|
|||||||
projRight = projRight.ScaledBy(1/projRight.Magnitude());
|
projRight = projRight.ScaledBy(1/projRight.Magnitude());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Project a point in model space to screen space, exactly as gl would; return
|
||||||
|
// units are pixels.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
Point2d GraphicsWindow::ProjectPoint(Vector p) {
|
Point2d GraphicsWindow::ProjectPoint(Vector p) {
|
||||||
|
Vector p3 = ProjectPoint3(p);
|
||||||
|
Point2d p2 = { p3.x, p3.y };
|
||||||
|
return p2;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Project a point in model space to screen space, exactly as gl would; return
|
||||||
|
// units are pixels. The z coordinate is also returned, also in pixels.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
Vector GraphicsWindow::ProjectPoint3(Vector p) {
|
||||||
|
double w;
|
||||||
|
Vector r = ProjectPoint4(p, &w);
|
||||||
|
return r.ScaledBy(scale/w);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Project a point in model space halfway into screen space. The scale is
|
||||||
|
// not applied, and the perspective divide isn't applied; instead the w
|
||||||
|
// coordinate is returned separately.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
Vector GraphicsWindow::ProjectPoint4(Vector p, double *w) {
|
||||||
p = p.Plus(offset);
|
p = p.Plus(offset);
|
||||||
|
|
||||||
Point2d r;
|
Vector r;
|
||||||
r.x = p.Dot(projRight) * scale;
|
r.x = p.Dot(projRight);
|
||||||
r.y = p.Dot(projUp) * scale;
|
r.y = p.Dot(projUp);
|
||||||
|
r.z = p.Dot(projUp.Cross(projRight));
|
||||||
|
|
||||||
|
*w = 1 + r.z*SS.cameraTangent*scale;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,57 +206,86 @@ void GraphicsWindow::AnimateOntoWorkplane(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWindow::HandlePointForZoomToFit(Vector p,
|
void GraphicsWindow::HandlePointForZoomToFit(Vector p,
|
||||||
Point2d *pmax, Point2d *pmin)
|
Point2d *pmax, Point2d *pmin, double *wmin, bool div)
|
||||||
{
|
{
|
||||||
Point2d p2 = ProjectPoint(p);
|
double w;
|
||||||
pmax->x = max(pmax->x, p2.x);
|
Vector pp = ProjectPoint4(p, &w);
|
||||||
pmax->y = max(pmax->y, p2.y);
|
if(div) {
|
||||||
pmin->x = min(pmin->x, p2.x);
|
pp = pp.ScaledBy(1.0/w);
|
||||||
pmin->y = min(pmin->y, p2.y);
|
}
|
||||||
|
|
||||||
|
pmax->x = max(pmax->x, pp.x);
|
||||||
|
pmax->y = max(pmax->y, pp.y);
|
||||||
|
pmin->x = min(pmin->x, pp.x);
|
||||||
|
pmin->y = min(pmin->y, pp.y);
|
||||||
|
*wmin = min(*wmin, w);
|
||||||
}
|
}
|
||||||
void GraphicsWindow::ZoomToFit(void) {
|
void GraphicsWindow::LoopOverPoints(
|
||||||
|
Point2d *pmax, Point2d *pmin, double *wmin, bool div)
|
||||||
|
{
|
||||||
|
HandlePointForZoomToFit(Vector::From(0, 0, 0), pmax, pmin, wmin, div);
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
Point2d pmax = { -1e12, -1e12 }, pmin = { 1e12, 1e12 };
|
|
||||||
|
|
||||||
HandlePointForZoomToFit(Vector::From(0, 0, 0), &pmax, &pmin);
|
|
||||||
|
|
||||||
for(i = 0; i < SS.entity.n; i++) {
|
for(i = 0; i < SS.entity.n; i++) {
|
||||||
Entity *e = &(SS.entity.elem[i]);
|
Entity *e = &(SS.entity.elem[i]);
|
||||||
if(!e->IsPoint()) continue;
|
if(!e->IsPoint()) continue;
|
||||||
if(!e->IsVisible()) continue;
|
if(!e->IsVisible()) continue;
|
||||||
HandlePointForZoomToFit(e->PointGetNum(), &pmax, &pmin);
|
HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, div);
|
||||||
}
|
}
|
||||||
Group *g = SS.GetGroup(activeGroup);
|
Group *g = SS.GetGroup(activeGroup);
|
||||||
for(i = 0; i < g->mesh.l.n; i++) {
|
for(i = 0; i < g->mesh.l.n; i++) {
|
||||||
STriangle *tr = &(g->mesh.l.elem[i]);
|
STriangle *tr = &(g->mesh.l.elem[i]);
|
||||||
HandlePointForZoomToFit(tr->a, &pmax, &pmin);
|
HandlePointForZoomToFit(tr->a, pmax, pmin, wmin, div);
|
||||||
HandlePointForZoomToFit(tr->b, &pmax, &pmin);
|
HandlePointForZoomToFit(tr->b, pmax, pmin, wmin, div);
|
||||||
HandlePointForZoomToFit(tr->c, &pmax, &pmin);
|
HandlePointForZoomToFit(tr->c, pmax, pmin, wmin, div);
|
||||||
}
|
}
|
||||||
for(i = 0; i < g->poly.l.n; i++) {
|
for(i = 0; i < g->poly.l.n; i++) {
|
||||||
SContour *sc = &(g->poly.l.elem[i]);
|
SContour *sc = &(g->poly.l.elem[i]);
|
||||||
for(j = 0; j < sc->l.n; j++) {
|
for(j = 0; j < sc->l.n; j++) {
|
||||||
HandlePointForZoomToFit(sc->l.elem[j].p, &pmax, &pmin);
|
HandlePointForZoomToFit(sc->l.elem[j].p, pmax, pmin, wmin, div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
void GraphicsWindow::ZoomToFit(void) {
|
||||||
|
// On the first run, ignore perspective.
|
||||||
|
Point2d pmax = { -1e12, -1e12 }, pmin = { 1e12, 1e12 };
|
||||||
|
double wmin = 1;
|
||||||
|
LoopOverPoints(&pmax, &pmin, &wmin, false);
|
||||||
|
|
||||||
pmax = pmax.ScaledBy(1/scale);
|
|
||||||
pmin = pmin.ScaledBy(1/scale);
|
|
||||||
double xm = (pmax.x + pmin.x)/2, ym = (pmax.y + pmin.y)/2;
|
double xm = (pmax.x + pmin.x)/2, ym = (pmax.y + pmin.y)/2;
|
||||||
double dx = pmax.x - pmin.x, dy = pmax.y - pmin.y;
|
double dx = pmax.x - pmin.x, dy = pmax.y - pmin.y;
|
||||||
|
|
||||||
offset = offset.Plus(projRight.ScaledBy(-xm)).Plus(
|
offset = offset.Plus(projRight.ScaledBy(-xm)).Plus(
|
||||||
projUp. ScaledBy(-ym));
|
projUp. ScaledBy(-ym));
|
||||||
|
|
||||||
|
// And based on this, we calculate the scale and offset
|
||||||
if(dx == 0 && dy == 0) {
|
if(dx == 0 && dy == 0) {
|
||||||
scale = 5;
|
scale = 5;
|
||||||
} else {
|
} else {
|
||||||
double scalex = 1e12, scaley = 1e12;
|
double scalex = 1e12, scaley = 1e12;
|
||||||
if(dx != 0) scalex = 0.9*width /dx;
|
if(dx != 0) scalex = 0.9*width /dx;
|
||||||
if(dy != 0) scaley = 0.9*height/dy;
|
if(dy != 0) scaley = 0.9*height/dy;
|
||||||
scale = min(100, min(scalex, scaley));
|
scale = min(scalex, scaley);
|
||||||
|
|
||||||
|
scale = min(100, scale);
|
||||||
|
scale = max(0.001, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then do another run, considering the perspective.
|
||||||
|
pmax.x = -1e12; pmax.y = -1e12;
|
||||||
|
pmin.x = 1e12; pmin.y = 1e12;
|
||||||
|
wmin = 1;
|
||||||
|
LoopOverPoints(&pmax, &pmin, &wmin, true);
|
||||||
|
|
||||||
|
// Adjust the scale so that no points are behind the camera
|
||||||
|
if(wmin < 0.1) {
|
||||||
|
double k = SS.cameraTangent;
|
||||||
|
// w = 1+k*scale*z
|
||||||
|
double zmin = (wmin - 1)/(k*scale);
|
||||||
|
// 0.1 = 1 + k*scale*zmin
|
||||||
|
// (0.1 - 1)/(k*zmin) = scale
|
||||||
|
scale = min(scale, (0.1 - 1)/(k*zmin));
|
||||||
}
|
}
|
||||||
scale = max(0.001, scale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWindow::MenuView(int id) {
|
void GraphicsWindow::MenuView(int id) {
|
||||||
|
@ -314,9 +314,9 @@ void Group::Draw(void) {
|
|||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
} else {
|
} else {
|
||||||
glxColor4d(0, 0.1, 0.1, 0.5);
|
glxColor4d(0, 0.1, 0.1, 0.5);
|
||||||
glPolygonOffset(-1, -1);
|
glxDepthRangeOffset(1);
|
||||||
glxFillPolygon(&poly);
|
glxFillPolygon(&poly);
|
||||||
glPolygonOffset(0, 0);
|
glxDepthRangeOffset(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
mesh.cpp
29
mesh.cpp
@ -258,28 +258,29 @@ bool SMesh::MakeFromInterferenceCheck(SMesh *srca, SMesh *srcb, SMesh *error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DWORD SMesh::FirstIntersectionWith(Point2d mp) {
|
DWORD SMesh::FirstIntersectionWith(Point2d mp) {
|
||||||
Vector gu = SS.GW.projRight, gv = SS.GW.projUp;
|
Vector p0 = Vector::From(mp.x, mp.y, 0);
|
||||||
Vector gn = (gu.Cross(gv)).WithMagnitude(1);
|
Vector gn = Vector::From(0, 0, 1);
|
||||||
|
|
||||||
Vector p0 = gu.ScaledBy(mp.x/SS.GW.scale).Plus(
|
|
||||||
gv.ScaledBy(mp.y/SS.GW.scale));
|
|
||||||
p0 = p0.Minus(SS.GW.offset);
|
|
||||||
|
|
||||||
double maxT = -1e12;
|
double maxT = -1e12;
|
||||||
DWORD face = 0;
|
DWORD face = 0;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
STriangle *tr = &(l.elem[i]);
|
STriangle tr = l.elem[i];
|
||||||
Vector n = tr->Normal();
|
tr.a = SS.GW.ProjectPoint3(tr.a);
|
||||||
|
tr.b = SS.GW.ProjectPoint3(tr.b);
|
||||||
|
tr.c = SS.GW.ProjectPoint3(tr.c);
|
||||||
|
|
||||||
|
Vector n = tr.Normal();
|
||||||
|
|
||||||
if(n.Dot(gn) < LENGTH_EPS) continue; // back-facing or on edge
|
if(n.Dot(gn) < LENGTH_EPS) continue; // back-facing or on edge
|
||||||
|
|
||||||
if(tr->ContainsPointProjd(gn, p0)) {
|
if(tr.ContainsPointProjd(gn, p0)) {
|
||||||
// Let our line have the form r(t) = p0 + gn*t
|
// Let our line have the form r(t) = p0 + gn*t
|
||||||
double t = (n.Dot((tr->a).Minus(p0)))/(n.Dot(gn));
|
double t = -(n.Dot((tr.a).Minus(p0)))/(n.Dot(gn));
|
||||||
if(t > maxT) {
|
if(t > maxT) {
|
||||||
maxT = t;
|
maxT = t;
|
||||||
face = tr->meta.face;
|
face = tr.meta.face;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -691,7 +692,7 @@ void SBsp3::DebugDraw(void) {
|
|||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
glPolygonOffset(-1, 0);
|
glxDepthRangeOffset(2);
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
glxVertex3v(tri.a);
|
glxVertex3v(tri.a);
|
||||||
glxVertex3v(tri.b);
|
glxVertex3v(tri.b);
|
||||||
@ -701,14 +702,14 @@ void SBsp3::DebugDraw(void) {
|
|||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
|
||||||
glPointSize(10);
|
glPointSize(10);
|
||||||
glPolygonOffset(-1, 0);
|
glxDepthRangeOffset(2);
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
glxVertex3v(tri.a);
|
glxVertex3v(tri.a);
|
||||||
glxVertex3v(tri.b);
|
glxVertex3v(tri.b);
|
||||||
glxVertex3v(tri.c);
|
glxVertex3v(tri.c);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glPolygonOffset(0, 0);
|
glxDepthRangeOffset(0);
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
|
||||||
more->DebugDraw();
|
more->DebugDraw();
|
||||||
|
@ -27,6 +27,8 @@ void SolveSpace::Init(char *cmdLine) {
|
|||||||
meshTol = ((int)CnfThawDWORD(1000, "MeshTolerance"))/1000.0;
|
meshTol = ((int)CnfThawDWORD(1000, "MeshTolerance"))/1000.0;
|
||||||
// View units
|
// View units
|
||||||
viewUnits = (Unit)CnfThawDWORD((DWORD)UNIT_MM, "ViewUnits");
|
viewUnits = (Unit)CnfThawDWORD((DWORD)UNIT_MM, "ViewUnits");
|
||||||
|
// Camera tangent (determines perspective)
|
||||||
|
cameraTangent = ((int)CnfThawDWORD(0, "CameraTangent"))/1e6;
|
||||||
// Recent files menus
|
// Recent files menus
|
||||||
for(i = 0; i < MAX_RECENT; i++) {
|
for(i = 0; i < MAX_RECENT; i++) {
|
||||||
char name[100];
|
char name[100];
|
||||||
@ -77,6 +79,8 @@ void SolveSpace::Exit(void) {
|
|||||||
CnfFreezeDWORD((int)(meshTol*1000), "MeshTolerance");
|
CnfFreezeDWORD((int)(meshTol*1000), "MeshTolerance");
|
||||||
// Display/entry units
|
// Display/entry units
|
||||||
CnfFreezeDWORD((int)viewUnits, "ViewUnits");
|
CnfFreezeDWORD((int)viewUnits, "ViewUnits");
|
||||||
|
// Camera tangent (determines perspective)
|
||||||
|
CnfFreezeDWORD((int)(cameraTangent*1e6), "CameraTangent");
|
||||||
ExitNow();
|
ExitNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,8 @@ void glxLockColorTo(double r, double g, double b);
|
|||||||
void glxUnlockColor(void);
|
void glxUnlockColor(void);
|
||||||
void glxColor3d(double r, double g, double b);
|
void glxColor3d(double r, double g, double b);
|
||||||
void glxColor4d(double r, double g, double b, double a);
|
void glxColor4d(double r, double g, double b, double a);
|
||||||
|
void glxDepthRangeOffset(int units);
|
||||||
|
void glxDepthRangeLockToFront(bool yes);
|
||||||
|
|
||||||
|
|
||||||
#define arraylen(x) (sizeof((x))/sizeof((x)[0]))
|
#define arraylen(x) (sizeof((x))/sizeof((x)[0]))
|
||||||
@ -253,6 +255,7 @@ public:
|
|||||||
Vector lightDir[2];
|
Vector lightDir[2];
|
||||||
double lightIntensity[2];
|
double lightIntensity[2];
|
||||||
double meshTol;
|
double meshTol;
|
||||||
|
double cameraTangent;
|
||||||
int CircleSides(double r);
|
int CircleSides(double r);
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UNIT_MM = 0,
|
UNIT_MM = 0,
|
||||||
|
17
textwin.cpp
17
textwin.cpp
@ -877,6 +877,12 @@ void TextWindow::ScreenChangeMeshTolerance(int link, DWORD v) {
|
|||||||
ShowTextEditControl(37, 3, str);
|
ShowTextEditControl(37, 3, str);
|
||||||
SS.TW.edit.meaning = EDIT_MESH_TOLERANCE;
|
SS.TW.edit.meaning = EDIT_MESH_TOLERANCE;
|
||||||
}
|
}
|
||||||
|
void TextWindow::ScreenChangeCameraTangent(int link, DWORD v) {
|
||||||
|
char str[1024];
|
||||||
|
sprintf(str, "%.3f", 1000*SS.cameraTangent);
|
||||||
|
ShowTextEditControl(43, 3, str);
|
||||||
|
SS.TW.edit.meaning = EDIT_CAMERA_TANGENT;
|
||||||
|
}
|
||||||
void TextWindow::ShowConfiguration(void) {
|
void TextWindow::ShowConfiguration(void) {
|
||||||
int i;
|
int i;
|
||||||
Printf(true, "%Ft material color-(r, g, b)");
|
Printf(true, "%Ft material color-(r, g, b)");
|
||||||
@ -908,6 +914,12 @@ void TextWindow::ShowConfiguration(void) {
|
|||||||
SS.meshTol,
|
SS.meshTol,
|
||||||
&ScreenChangeMeshTolerance, 0,
|
&ScreenChangeMeshTolerance, 0,
|
||||||
SS.group.elem[SS.group.n-1].mesh.l.n);
|
SS.group.elem[SS.group.n-1].mesh.l.n);
|
||||||
|
|
||||||
|
Printf(false, "");
|
||||||
|
Printf(false, "%Ft perspective factor (0 for isometric)%E");
|
||||||
|
Printf(false, "%Ba %3 %Fl%Ll%f%D[change]%E",
|
||||||
|
SS.cameraTangent*1000,
|
||||||
|
&ScreenChangeCameraTangent, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextWindow::EditControlDone(char *s) {
|
void TextWindow::EditControlDone(char *s) {
|
||||||
@ -974,6 +986,11 @@ void TextWindow::EditControlDone(char *s) {
|
|||||||
SS.GenerateAll(0, INT_MAX);
|
SS.GenerateAll(0, INT_MAX);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EDIT_CAMERA_TANGENT: {
|
||||||
|
SS.cameraTangent = (min(2, max(0, atof(s))))/1000.0;
|
||||||
|
InvalidateGraphics();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SS.later.showTW = true;
|
SS.later.showTW = true;
|
||||||
HideTextEditControl();
|
HideTextEditControl();
|
||||||
|
8
ui.h
8
ui.h
@ -63,6 +63,7 @@ public:
|
|||||||
static const int EDIT_LIGHT_INTENSITY = 4;
|
static const int EDIT_LIGHT_INTENSITY = 4;
|
||||||
static const int EDIT_COLOR = 5;
|
static const int EDIT_COLOR = 5;
|
||||||
static const int EDIT_MESH_TOLERANCE = 6;
|
static const int EDIT_MESH_TOLERANCE = 6;
|
||||||
|
static const int EDIT_CAMERA_TANGENT = 7;
|
||||||
struct {
|
struct {
|
||||||
int meaning;
|
int meaning;
|
||||||
int i;
|
int i;
|
||||||
@ -115,6 +116,7 @@ public:
|
|||||||
static void ScreenChangeLightIntensity(int link, DWORD v);
|
static void ScreenChangeLightIntensity(int link, DWORD v);
|
||||||
static void ScreenChangeColor(int link, DWORD v);
|
static void ScreenChangeColor(int link, DWORD v);
|
||||||
static void ScreenChangeMeshTolerance(int link, DWORD v);
|
static void ScreenChangeMeshTolerance(int link, DWORD v);
|
||||||
|
static void ScreenChangeCameraTangent(int link, DWORD v);
|
||||||
|
|
||||||
void EditControlDone(char *s);
|
void EditControlDone(char *s);
|
||||||
};
|
};
|
||||||
@ -217,9 +219,13 @@ public:
|
|||||||
|
|
||||||
void NormalizeProjectionVectors(void);
|
void NormalizeProjectionVectors(void);
|
||||||
Point2d ProjectPoint(Vector p);
|
Point2d ProjectPoint(Vector p);
|
||||||
|
Vector ProjectPoint3(Vector p);
|
||||||
|
Vector ProjectPoint4(Vector p, double *w);
|
||||||
void AnimateOntoWorkplane(void);
|
void AnimateOntoWorkplane(void);
|
||||||
Vector VectorFromProjs(Vector rightUpForward);
|
Vector VectorFromProjs(Vector rightUpForward);
|
||||||
void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin);
|
void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin,
|
||||||
|
double *wmin, bool div);
|
||||||
|
void LoopOverPoints(Point2d *pmax, Point2d *pmin, double *wmin, bool div);
|
||||||
void ZoomToFit(void);
|
void ZoomToFit(void);
|
||||||
|
|
||||||
hGroup activeGroup;
|
hGroup activeGroup;
|
||||||
|
Loading…
Reference in New Issue
Block a user