From: Arthur <ajs...@op...> - 2003-02-20 13:09:20
|
Further adventures with primitivesShaun - How does one get one's greedy hands on what you have done. Interested both as to the specifics of what you have implemented, and for the tutorial value of understanding, in full specifics, how you have accomplished it. Art ----- Original Message ----- From: Press, Shaun To: 'vis...@li...' Cc: 'hen...@an...' Sent: Wednesday, February 19, 2003 5:48 PM Subject: [Visualpython-users] Further adventures with primitives I have managed to add Tetrahedron, Pyramid and Frustum to the primitive shapes in my copy of Visual Python. The terahedron and pyramid a pretty simple to do as they are a specific form of the cone shape. In the cone.cpp file there is a section devoted to calculating the level of detail for the shape. The idea is that closer shapes are drawn with a lot of detail while distant shapes require less. Depending on the size and location of the cone it can be drawn with 20 panels down to 5 panels. The number of panels is passed to the cyl_model object which returns the vertices required to draw the shape. To draw a pyramid, simply drop the level of details code and just pass 5 to the cyl_model::get(n) method. This will return the vertices of a cube. Of course a cube isn't what was asked for but some extra work is done. The tip of the cone is calculated by passing a vector (2,0,0) to the mct.project method. This point is the middle of the base, moved two units along the x-axis. Inside the projection loop every second vertex is replaced by the tip vertex, which when rendered makes the faces of the shape meet at the tip. This results in a cone/pyramid/tetrahedron depending on the number of faces required. For tetrahedron simply use the 4 vertices rather than 5 for a pyramid. As for the actual rendering by openGL, the array of vertices is used to draw GL_TRIANGLE_STRIP geometries. This is a pretty flexible and efficient way to do it, as GL_QUAD_STRIP geometries require some extra vertex calculations. In the case of a cone the triangle strip vertecies go v1 |\ |\v3 | \ | \ | \ | \ v0 | \|v2\| etc (hopefully this crude ascii diagram comes out ok) OpenGl fills in both sides of the triangle ie v0,v1,v2 and v1,v2,v3 are filled when drawn. Of course when drawing a cone/pyramid/tetrahedron there is obvious redundancy as v1==v3==v5 etc. A more efficient method would be to use GL_TRIANGLE_FAN which has a central point for all triangles and the vertices for the base points eg tip would be v0 and v1, v2, v3 etc would be the base points. The triangles would the be (v0,v1,v2), (v0,v2,v3) etc Using this method would cut the calculating/drawing time for cones etc in half. The final rendering is for the base. This is done using the GL_POLYGON geometry which fills in a shape enclosed by points v0,v2,v4 etc ie the triangle base points. The frustum was a little more frustrating to get right. In the end I made a copy of cylmodel.h and called it frustmodel.h. I then modifed the method that returns the vertices of the cylinder to set the top vertices at half the radius of the bottom ones. Trying to do this inside the frustum projection loop in frustum.cpp caused some bizzare results. I had hoped to avoid making almost identical copies of other modules as this adds to code bloat, but for the moment this will do. I haven't added any new attributes to the shapes, instead relying on the ones provided. That means that the size of the base of the pyramid/tetrahedon uses the radius attribute and is the distance from the mid point of the base to the corner vertex. For the frustum the radius at the top is fixed to be half the radius of the base. BTW As I remarked in my first post frustum is not a good name for this shape, at least internally, as it causes compile errors due to the clash with the frustum methods used to handle the camera in openGl. I've called it frustm in the short term but does anyone have a better suggestion? |