Commit 58f9ec28 authored by Martin Schultz's avatar Martin Schultz
Browse files

added Torus to ACG Primitives

Use ACG Torus implementation in glutPrimitiveNode
parent 28f10a00
......@@ -52,7 +52,6 @@
#include "GLPrimitives.hh"
#include <ACG/GL/IRenderer.hh>
namespace ACG {
//========================================================================
......@@ -1448,5 +1447,119 @@ void GLTetrahedron::updateVBO()
}
}
//------------------------------------------------------------------------
GLTorus::GLTorus(GLdouble innerRadius,
GLdouble outerRadius,
GLint nsides, GLint rings):
rings_(rings),
nsides_(nsides),
innerRadius_(innerRadius),
outerRadius_(outerRadius)
{
updateVBO();
}
GLTorus::~GLTorus()
{
}
//------------------------------------------------------------------------
int GLTorus::getNumTriangles()
{
return rings_*nsides_*2;
}
//------------------------------------------------------------------------
void GLTorus::updateVBO()
{
// build the Torus in two steps.
// First build a unit Ring in XZ plane.
// Then copy and rotate the ring around z axis to form a torus.
//
// create faces and normals + texcoordinates.
// Inner seam is top/bottom of texture
std::vector<Vec3f> points;
std::vector<Vec3f> normals;
std::vector<Vec2f> texCoords;
std::vector<Vec3f> unitRing;
float ringSegmentAngle = 2 * M_PI / nsides_;
float torusSegmentAngle = 2 * M_PI / rings_;
// generate a unit ring with n sides
for (int i = 0 ; i < nsides_ ; ++i)
{
Vec3f ringPoint = Vec3f(cos(ringSegmentAngle * i),0.0f,sin(ringSegmentAngle *i));
unitRing.push_back(ringPoint);
////cosCache[i] = cos(angle);
}
for(int j = 0; j < rings_ ; ++j)
{
Vec3f torusPoint;
int side = 0;
for(Vec3f point : unitRing)
{
//scale the unit Ring
torusPoint = point * (1.f/innerRadius_);
//translate the unit Ring
torusPoint +=Vec3f(outerRadius_ + innerRadius_,0,0);
//rotate the translated ring around the z axis
Vec3f pointOnTorus = Vec3f(torusPoint[0] * cos(j*torusSegmentAngle) + torusPoint[1] * sin(j*torusSegmentAngle),
torusPoint[0] * -sin(j*torusSegmentAngle) + torusPoint[1] * cos(j*torusSegmentAngle),
torusPoint[2]);
points.push_back(pointOnTorus);
//the normal does not have to be translated or scaled
Vec3f normalOnTorus = Vec3f(point[0] * cos(j*torusSegmentAngle) + point[1] * sin(j*torusSegmentAngle),
point[0] * -sin(j*torusSegmentAngle) + point[1] * cos(j*torusSegmentAngle),
point[2]);
// probably not necessary as we are working with the unit circle
normalOnTorus.normalize();
normals.push_back(normalOnTorus);
// texcoords are a simple uv unwrap of the torus cut open.
// j/rings_ is directly the u component
// the ring segment gives us the v component
texCoords.push_back(Vec2f(j/rings_,side/nsides_));
++side;
}
}
// points are now stored one ring after the other in the points vector.
// creating a triangle is fairly easy adding nsides_ to the current index gives the same point on the next ring.
// create triangles as point on ring -> same point on next ring -> next point on next ring.
int end = rings_*nsides_;
int segmentOffset = nsides_;
int oddIndex = 0;
for(int i = 0 ; i < end ; ++i)
{
if((i+1) % nsides_ == 0)
{
segmentOffset = 0;
oddIndex = -nsides_;
}
else
{
segmentOffset = nsides_;
oddIndex = 0;
}
// first face (lower left triangle)
Vec3f p[3] = { points[i] , points[(i+nsides_)%end] , points[(i+segmentOffset+1)%end] };
Vec3f n[3] = { normals[i] , normals[(i+nsides_)%end] , normals[(i+segmentOffset+1)%end] };
Vec2f t[3] = { texCoords[i] , texCoords[(i+nsides_)%end] , texCoords[(i+segmentOffset+1)%end] };
addTriangleToVBO(p, n, t);
// second face (upper right triangle)
Vec3f p2[3] = { points[(i+1 + oddIndex)%end] , points[(i)%end] , points[(i+segmentOffset+1)%end] };
Vec3f n2[3] = { normals[(i+1 + oddIndex)%end] , normals[(i)%end] , normals[(i+segmentOffset+1)%end] };
Vec2f t2[3] = { texCoords[(i+1 + oddIndex)%end] , texCoords[(i)%end], texCoords[(i+segmentOffset+1)%end] };
addTriangleToVBO(p2, n2, t2);
}
}
//------------------------------------------------------------------------
}
......@@ -359,6 +359,30 @@ private:
//------------------------------------------------------------------------
// axis-aligned Torus centered at origin
class ACGDLLEXPORT GLTorus: public GLPrimitive {
public:
GLTorus(GLdouble innerRadius,
GLdouble outerRadius,
GLint nsides, GLint rings);
~GLTorus();
int getNumTriangles();
private:
void updateVBO();
int rings_;
int nsides_;
float innerRadius_;
float outerRadius_;
};
//------------------------------------------------------------------------
} // namespace ACG
#endif // ACG_GLPRIMITIVES_HH defined
......@@ -374,8 +374,7 @@ GlutPrimitiveNode::draw_obj(GLState& _state, size_t _idx) const
break;
case TORUS:
ACG::GLDisk(primitives_[_idx].slices,primitives_[_idx].stacks, primitives_[_idx].innersize, primitives_[_idx].size).draw(_state, Vec3f(0.0f),(Vec3f)primitives_[_idx].axis);
//glutSolidTorus(primitives_[_idx].innersize, primitives_[_idx].size, primitives_[_idx].slices, primitives_[_idx].stacks);
ACG::GLTorus(primitives_[_idx].innersize, primitives_[_idx].size, primitives_[_idx].slices, primitives_[_idx].stacks).draw_primitive();
break;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment