qglengine: direct primitive editor
git-svn-id: svn://db.shs.com.ru/libs@687 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
@@ -87,7 +87,7 @@ Mesh * Primitive::cube(float width, float length, float height) {
|
||||
}
|
||||
|
||||
|
||||
Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float width, float length, float height) {
|
||||
Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float width, float length, float height, float end_angle) {
|
||||
Mesh * ret = new Mesh();
|
||||
QVector<QVector3D> & v(ret->vertices ());
|
||||
QVector<QVector3D> & n(ret->normals ());
|
||||
@@ -96,6 +96,7 @@ Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float width, float
|
||||
double hh = height / 2.f;
|
||||
int hseg = segments_h + 1, wlseg = segments_wl + 1;
|
||||
double crw, crl, a, ch, twl;
|
||||
double eang = deg2rad * end_angle;
|
||||
|
||||
QVector3D cp;
|
||||
for (int i = 0; i <= hseg; i++) {
|
||||
@@ -106,10 +107,12 @@ Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float width, float
|
||||
crl = twl * length;
|
||||
int cvcnt = wlseg * 2;
|
||||
for (int j = 0; j < cvcnt; j++) {
|
||||
a = (double)j / (cvcnt - 1) * M_2PI;
|
||||
a = (double)j / (cvcnt - 1) * eang;
|
||||
cp.setX(crl * cos(a));
|
||||
cp.setY(crw * sin(a));
|
||||
v << cp; t << QVector2D((double)j / (cvcnt - 1), ch/2.f + 0.5f);
|
||||
v << cp;
|
||||
t << QVector2D((double)j / (cvcnt - 1), ch/2.f + 0.5f);
|
||||
n << (cp / QVector3D(length * length, width * width, height * height)).normalized();
|
||||
int si = v.size() - 1;
|
||||
if (j > 0 && i > 0) {
|
||||
ind << Vector3i(si - cvcnt - 1, si, si - 1);
|
||||
@@ -117,16 +120,22 @@ Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float width, float
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
n.resize(v.size());
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
n[i] = v[i].normalized();
|
||||
|
||||
if (end_angle < 360.) {
|
||||
Mesh * cap = Primitive::disc(segments_h+1, length, height, 180);
|
||||
cap->rotatePoints(90, 0, 1, 0);
|
||||
cap->rotatePoints(-90, 0, 0, 1);
|
||||
ret->append(cap);
|
||||
cap->flipNormals();
|
||||
cap->rotatePoints(end_angle, 0, 0, 1);
|
||||
cap->scalePoints(QVector3D((cos(eang)*cos(eang)*width+sin(eang)*sin(eang)*length)/width, (cos(eang)*cos(eang)*length+sin(eang)*sin(eang)*width)/length, 1));
|
||||
ret->append(cap);
|
||||
delete cap;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Mesh * Primitive::disc(int segments, float width, float length, bool up, float end_angle) {
|
||||
Mesh * Primitive::disc(int segments, float width, float length, float end_angle) {
|
||||
Mesh * ret = new Mesh();
|
||||
QVector<QVector3D> & v(ret->vertices ());
|
||||
QVector<QVector3D> & n(ret->normals ());
|
||||
@@ -136,6 +145,7 @@ Mesh * Primitive::disc(int segments, float width, float length, bool up, float e
|
||||
segments = qMax(segments + 1, 4);
|
||||
QVector3D cp;
|
||||
v << QVector3D();
|
||||
n << QVector3D(0, 0, 1);
|
||||
t << QVector2D(0.5f, 0.5f);
|
||||
end_angle *= deg2rad;
|
||||
for (int i = 0; i < segments; i++) {
|
||||
@@ -143,20 +153,11 @@ Mesh * Primitive::disc(int segments, float width, float length, bool up, float e
|
||||
cp.setX(length / 2. * cos(a));
|
||||
cp.setY(width / 2. * sin(a));
|
||||
v << cp;
|
||||
n << QVector3D(0, 0, 1);
|
||||
t << QVector2D(cp.x() / width + 0.5f, cp.y() / length + 0.5f);
|
||||
int si = v.size() - 1;
|
||||
if (i > 0) {
|
||||
if (up)
|
||||
ind << Vector3i(si - 1, si, 0);
|
||||
else
|
||||
ind << Vector3i(si, si - 1, 0);
|
||||
}
|
||||
if (i > 0) ind << Vector3i(si - 1, si, 0);
|
||||
}
|
||||
|
||||
n.resize(v.size());
|
||||
for (int i = 0; i < v.size(); i++)
|
||||
n[i] = QVector3D(0, 0, up ? 1 : -1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -172,6 +173,8 @@ QVector3D coneNormal(double rx, double ry, double height, double ang) {
|
||||
norm.setZ(norm.length() * tan(ca));
|
||||
return norm.normalized();
|
||||
}
|
||||
|
||||
|
||||
Mesh * Primitive::cone(int segments, float width, float length, float height) {
|
||||
Mesh * ret = new Mesh();
|
||||
QVector<QVector3D> & v(ret->vertices ());
|
||||
@@ -200,7 +203,8 @@ Mesh * Primitive::cone(int segments, float width, float length, float height) {
|
||||
ind << Vector3i(si - 1, si - 2, si);
|
||||
}
|
||||
|
||||
Mesh * cap = Primitive::disc(segments, width, length, false);
|
||||
Mesh * cap = Primitive::disc(segments, width, length);
|
||||
cap->flipNormals();
|
||||
ret->append(cap);
|
||||
delete cap;
|
||||
|
||||
@@ -208,7 +212,7 @@ Mesh * Primitive::cone(int segments, float width, float length, float height) {
|
||||
}
|
||||
|
||||
|
||||
Mesh * Primitive::cylinder(int segments, float width, float length, float height) {
|
||||
Mesh * Primitive::cylinder(int segments, float width, float length, float height, float end_angle) {
|
||||
Mesh * ret = new Mesh();
|
||||
QVector<QVector3D> & v(ret->vertices ());
|
||||
QVector<QVector3D> & n(ret->normals ());
|
||||
@@ -218,12 +222,14 @@ Mesh * Primitive::cylinder(int segments, float width, float length, float height
|
||||
int seg = qMax(segments + 1, 4);
|
||||
double rx = width / 2., ry = length / 2.;
|
||||
QVector3D cp, norm;
|
||||
double eang = deg2rad * end_angle;
|
||||
|
||||
for (int i = 0; i < seg; i++) {
|
||||
double a = (double)i / (seg - 1) * M_2PI;
|
||||
double a = (double)i / (seg - 1) * eang;
|
||||
cp.setX(ry * cos(a));
|
||||
cp.setY(rx * sin(a));
|
||||
cp.setZ(0.);
|
||||
norm = cp.normalized();
|
||||
norm = (cp / QVector3D(length * length, width * width, 1)).normalized();
|
||||
v << cp;
|
||||
cp.setZ(height);
|
||||
v << cp;
|
||||
@@ -237,14 +243,27 @@ Mesh * Primitive::cylinder(int segments, float width, float length, float height
|
||||
}
|
||||
}
|
||||
|
||||
Mesh * cap = Primitive::disc(segments, width, length, false);
|
||||
Mesh * cap = Primitive::disc(segments, width, length, end_angle);
|
||||
cap->flipNormals();
|
||||
ret->append(cap);
|
||||
delete cap;
|
||||
cap = Primitive::disc(segments, width, length, true);
|
||||
cap->translatePoints(QVector3D(0., 0., height));
|
||||
cap->flipNormals();
|
||||
ret->append(cap);
|
||||
delete cap;
|
||||
|
||||
if (end_angle < 360.) {
|
||||
Mesh * cap = Primitive::plane(length/2, height);
|
||||
cap->rotatePoints(90, 1, 0, 0);
|
||||
//cap->rotatePoints(-90, 0, 0, 1);
|
||||
cap->translatePoints(length/4, 0, height/2);
|
||||
ret->append(cap);
|
||||
cap->flipNormals();
|
||||
cap->rotatePoints(end_angle, 0, 0, 1);
|
||||
cap->scalePoints(QVector3D((cos(eang)*cos(eang)*width+sin(eang)*sin(eang)*length)/width, (cos(eang)*cos(eang)*length+sin(eang)*sin(eang)*width)/length, 1));
|
||||
ret->append(cap);
|
||||
delete cap;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -304,16 +323,14 @@ Mesh * Primitive::torus(int segments_main, int segments_second, float radius_mai
|
||||
pcnt = v.size();
|
||||
}
|
||||
if (end_angle < 360.) {
|
||||
Mesh * cap = Primitive::disc(segments_second-1, radius_second * 2, radius_second * 2, true);
|
||||
Mesh * cap = Primitive::disc(segments_second-1, radius_second * 2, radius_second * 2);
|
||||
cap->rotatePoints(90, 1, 0, 0);
|
||||
cap->translatePoints(radius_main, 0, 0);
|
||||
ret->append(cap);
|
||||
delete cap;
|
||||
cap = Primitive::disc(segments_second-1, radius_second * 2, radius_second * 2, false);
|
||||
cap->rotatePoints(90, 1, 0, 0);
|
||||
cap->translatePoints(radius_main, 0, 0);
|
||||
cap->flipNormals();
|
||||
cap->rotatePoints(end_angle, 0, 0, 1);
|
||||
ret->append(cap);
|
||||
delete cap;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user