+ Fixed bug in SGSHAPE::Prepare() : bad assignment of color pointer
+ Reworked s3d_plugin_demo2.cpp to use per-vertex-per-face normals + Reworked s3d_plugin_idf.cpp to use per-vertex-per-face normals
This commit is contained in:
parent
eab70be17b
commit
008d8a540a
|
@ -40,6 +40,7 @@
|
|||
#include "3d_cache/sg/sg_normals.h"
|
||||
#include "3d_cache/sg/sg_shape.h"
|
||||
#include "3d_cache/sg/sg_version.h"
|
||||
#include "3d_cache/sg/sg_helpers.h"
|
||||
#include "3d_info.h"
|
||||
#include "plugins/3dapi/c3dmodel.h"
|
||||
|
||||
|
@ -437,3 +438,24 @@ void S3D::GetLibVersion( unsigned char* Major, unsigned char* Minor,
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SGVECTOR S3D::CalcTriNorm( const SGPOINT& p1, const SGPOINT& p2, const SGPOINT& p3 )
|
||||
{
|
||||
glm::dvec3 tri = glm::dvec3( 0.0, 0.0, 0.0 );
|
||||
glm::dvec3 pts[3];
|
||||
|
||||
pts[0] = glm::dvec3( p1.x, p1.y, p1.z );
|
||||
pts[1] = glm::dvec3( p2.x, p2.y, p2.z );
|
||||
pts[2] = glm::dvec3( p3.x, p3.y, p3.z );
|
||||
|
||||
// degenerate points are given a default 0, 0, 1 normal
|
||||
if( S3D::degenerate( pts ) )
|
||||
return SGVECTOR( 0.0, 0.0, 1.0 );
|
||||
|
||||
// normal
|
||||
tri = cross( pts[1] - pts[0], pts[2] - pts[0] );
|
||||
normalize( tri );
|
||||
|
||||
return SGVECTOR( tri.x, tri.y, tri.z );
|
||||
}
|
||||
|
|
|
@ -316,33 +316,48 @@ bool SGCOORDS::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
|||
}
|
||||
|
||||
|
||||
bool SGCOORDS::CalcNormals( SGNODE** aPtr )
|
||||
bool SGCOORDS::CalcNormals( SGFACESET* callingNode, SGNODE** aPtr )
|
||||
{
|
||||
if( aPtr )
|
||||
*aPtr = NULL;
|
||||
|
||||
if( NULL == m_Parent )
|
||||
if( NULL == m_Parent || NULL == callingNode )
|
||||
return false;
|
||||
|
||||
// the parent and all references must have indices; collect all
|
||||
// indices into one std::vector<>
|
||||
std::vector< int > ilist;
|
||||
((SGFACESET*)m_Parent)->GatherCoordIndices( ilist );
|
||||
SGNORMALS* np = NULL;
|
||||
|
||||
std::list< SGNODE* >::iterator sB = m_BackPointers.begin();
|
||||
std::list< SGNODE* >::iterator eB = m_BackPointers.end();
|
||||
|
||||
while( sB != eB )
|
||||
if( callingNode == m_Parent )
|
||||
{
|
||||
SGFACESET* fp = (SGFACESET*)(*sB);
|
||||
fp->GatherCoordIndices( ilist );
|
||||
++sB;
|
||||
((SGFACESET*)m_Parent)->GatherCoordIndices( ilist );
|
||||
|
||||
std::list< SGNODE* >::iterator sB = m_BackPointers.begin();
|
||||
std::list< SGNODE* >::iterator eB = m_BackPointers.end();
|
||||
|
||||
while( sB != eB )
|
||||
{
|
||||
SGFACESET* fp = (SGFACESET*)(*sB);
|
||||
fp->GatherCoordIndices( ilist );
|
||||
++sB;
|
||||
}
|
||||
|
||||
np = ((SGFACESET*)m_Parent)->m_Normals;
|
||||
|
||||
if( !np )
|
||||
np = new SGNORMALS( m_Parent );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
callingNode->GatherCoordIndices( ilist );
|
||||
np = callingNode->m_Normals;
|
||||
|
||||
SGNORMALS* np = ((SGFACESET*)m_Parent)->m_Normals;
|
||||
if( !np )
|
||||
np = new SGNORMALS( callingNode );
|
||||
|
||||
if( !np )
|
||||
np = new SGNORMALS( m_Parent );
|
||||
}
|
||||
|
||||
if( S3D::CalcTriangleNormals( coords, ilist, np->norms ) )
|
||||
{
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <vector>
|
||||
#include "3d_cache/sg/sg_node.h"
|
||||
|
||||
class SGFACESET;
|
||||
|
||||
class SGCOORDS : public SGNODE
|
||||
{
|
||||
public:
|
||||
|
@ -60,7 +62,7 @@ public:
|
|||
* calculates normals for this coordinate list and sets the
|
||||
* normals list in the parent SGFACESET
|
||||
*/
|
||||
bool CalcNormals( SGNODE** aPtr );
|
||||
bool CalcNormals( SGFACESET* callingNode, SGNODE** aPtr = NULL );
|
||||
|
||||
void ReNameNodes( void );
|
||||
bool WriteVRML( std::ofstream& aFile, bool aReuseFlag );
|
||||
|
|
|
@ -1043,21 +1043,19 @@ void SGFACESET::GatherCoordIndices( std::vector< int >& aIndexList )
|
|||
|
||||
bool SGFACESET::CalcNormals( SGNODE** aPtr )
|
||||
{
|
||||
SGCOORDS* coords = m_Coords;
|
||||
|
||||
if( m_RCoords )
|
||||
{
|
||||
SGFACESET* fp = (SGFACESET*) m_RCoords->GetParent();
|
||||
coords = m_RCoords;
|
||||
|
||||
if( !fp )
|
||||
return false;
|
||||
|
||||
return fp->CalcNormals( aPtr );
|
||||
}
|
||||
|
||||
if( NULL == m_Coords || m_Coords->coords.empty() )
|
||||
if( NULL == coords || coords->coords.empty() )
|
||||
return false;
|
||||
|
||||
if( m_Normals && !m_Normals->norms.empty( ) )
|
||||
return true;
|
||||
|
||||
return m_Coords->CalcNormals( aPtr );
|
||||
if( m_RNormals && !m_RNormals->norms.empty( ) )
|
||||
return true;
|
||||
|
||||
return coords->CalcNormals( this, aPtr );
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "3d_cache/sg/sg_helpers.h"
|
||||
#include "3d_cache/sg/sg_node.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
// formats a floating point number for text output to a VRML file
|
||||
|
@ -311,7 +310,7 @@ bool S3D::ReadColor( std::ifstream& aFile, SGCOLOR& aColor )
|
|||
}
|
||||
|
||||
|
||||
static bool degenerate( glm::dvec3* pts )
|
||||
bool S3D::degenerate( glm::dvec3* pts )
|
||||
{
|
||||
double dx, dy, dz;
|
||||
|
||||
|
@ -342,7 +341,7 @@ static bool degenerate( glm::dvec3* pts )
|
|||
|
||||
static void calcTriad( glm::dvec3* pts, glm::dvec3& tri )
|
||||
{
|
||||
if( degenerate( pts ) )
|
||||
if( S3D::degenerate( pts ) )
|
||||
{
|
||||
// degenerate points should contribute nothing to the result
|
||||
tri = glm::dvec3( 0.0, 0.0, 0.0 );
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <vector>
|
||||
#include "plugins/3dapi/sg_base.h"
|
||||
#include "plugins/3dapi/sg_types.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class SGNORMALS;
|
||||
class SGCOORDS;
|
||||
|
@ -153,6 +154,8 @@ class SGCOORDINDEX;
|
|||
|
||||
namespace S3D
|
||||
{
|
||||
bool degenerate( glm::dvec3* pts );
|
||||
|
||||
//
|
||||
// Normals calculations from triangles
|
||||
//
|
||||
|
|
|
@ -605,7 +605,7 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
|
|||
return true;
|
||||
}
|
||||
|
||||
if( NULL == m_Appearance )
|
||||
if( NULL == pa )
|
||||
{
|
||||
m.m_MaterialIdx = 0;
|
||||
}
|
||||
|
|
|
@ -281,7 +281,7 @@ void C3D_MODEL_VIEWER::OnPaint( wxPaintEvent &event )
|
|||
|
||||
m_ogl_3dmodel->Draw_opaque();
|
||||
//m_ogl_3dmodel->Draw_transparent();
|
||||
m_ogl_3dmodel->Draw_bboxes();
|
||||
//m_ogl_3dmodel->Draw_bboxes();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
|
|
@ -42,6 +42,12 @@ struct S3D_POINT;
|
|||
|
||||
namespace S3D
|
||||
{
|
||||
/**
|
||||
* Function CalcTriNorm
|
||||
* returns the normal vector of a triangle described by vertices p1, p2, p3
|
||||
*/
|
||||
SGLIB_API SGVECTOR CalcTriNorm( const SGPOINT& p1, const SGPOINT& p2, const SGPOINT& p3 );
|
||||
|
||||
/**
|
||||
* Function WriteCache
|
||||
* writes the SGNODE tree to a binary cache file
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#add_subdirectory( demo )
|
||||
add_subdirectory( demo )
|
||||
add_subdirectory( idf )
|
||||
add_subdirectory( vrml )
|
||||
|
|
|
@ -136,33 +136,31 @@ bool CanRender( void )
|
|||
|
||||
SCENEGRAPH* Load( char const* aFileName )
|
||||
{
|
||||
// For this demonstration we create a tetrahedron and
|
||||
// paint its faces Magenta Red Green Blue. Steps:
|
||||
// * Create a top level transform tx0 which represent the VRML file
|
||||
// * Create a child transform tx1, parent tx0, to define the tetrahedron
|
||||
// + Create 'shape' to define one facet
|
||||
// ++ Create a 'face' to hold vertices and indices
|
||||
// +++ Create 'cp' which is the coordinate list
|
||||
// +++ Create 'np' which is the per-vertex normals list
|
||||
// +++ Create 'coordIndex' which is the (triangular) vertex index list
|
||||
// for facet1 of the tetrahedron
|
||||
// ++ Create a 'material' to define the appearance of 'shape'
|
||||
// **
|
||||
// + shape->NewNode() to define next facet
|
||||
// ++ face->NewNode() for a new facet
|
||||
// +++ Add Ref to 'cp' for coordinate list
|
||||
// +++ Add Ref to 'np' for normals list
|
||||
// +++ coordIndex->NewNode() for vertex index list of new facet
|
||||
// ++ material->NewNode() for material of new facet
|
||||
// + repeat twice from ** to produce last 2 facets
|
||||
// * Create a child transform tx2, parent tx0, for a referenced tetrahedron
|
||||
// + Set a translation and rotation so that this is distinct from tx1
|
||||
// + Add Reference to tx1
|
||||
// ALL DONE: we now have:
|
||||
// tx0
|
||||
// - contains tx1 which contains all elements of a tetrahedron
|
||||
// - contains tx0 which contains a reference to tx1 and offsets it so
|
||||
// that it renders in a different position
|
||||
// For this demonstration we create a tetrahedron (tx1) consisting of a SCENEGRAPH
|
||||
// (VRML Transform) which in turn contains 4 SGSHAPE (VRML Shape) objects
|
||||
// representing each of the sides of the tetrahedron. Each Shape is associated
|
||||
// with a color (SGAPPEARANCE) and a SGFACESET (VRML Geometry->indexedFaceSet).
|
||||
// Each SGFACESET is associated with a vertex list (SGCOORDS), a per-vertex normals
|
||||
// list (SGNORMALS), and a coordinate index (SGCOORDINDEX). One shape is used to
|
||||
// represent each face so that we may use per-vertex-per-face normals.
|
||||
//
|
||||
// The tetrahedron in turn is a child of a top level SCENEGRAPH (tx0) which has
|
||||
// a second SCENEGRAPH child (tx2) which is a transformation of the tetrahedron tx1
|
||||
// (rotation + translation). This demonstrates the reuse of components within
|
||||
// the model heirarchy.
|
||||
|
||||
// define the vertices of the tetrahedron
|
||||
// face 1: 0, 3, 1
|
||||
// face 2: 0, 2, 3
|
||||
// face 3: 1, 3, 2
|
||||
// face 4: 0, 1, 2
|
||||
double SQ2 = sqrt( 0.5 );
|
||||
SGPOINT vert[4];
|
||||
vert[0] = SGPOINT( 1.0, 0.0, -SQ2 );
|
||||
vert[1] = SGPOINT( -1.0, 0.0, -SQ2 );
|
||||
vert[2] = SGPOINT( 0.0, 1.0, SQ2 );
|
||||
vert[3] = SGPOINT( 0.0, -1.0, SQ2 );
|
||||
|
||||
|
||||
// create the top level transform; this will hold all other
|
||||
// scenegraph objects; a transform may hold other transforms and
|
||||
|
@ -172,7 +170,7 @@ SCENEGRAPH* Load( char const* aFileName )
|
|||
// create the transform which will house the shapes
|
||||
IFSG_TRANSFORM* tx1 = new IFSG_TRANSFORM( tx0->GetRawPtr() );
|
||||
|
||||
// add a shape which we will use to define a tetrahedron; shapes
|
||||
// add a shape which we will use to define one face of the tetrahedron; shapes
|
||||
// hold facesets and appearances
|
||||
IFSG_SHAPE* shape = new IFSG_SHAPE( *tx1 );
|
||||
|
||||
|
@ -182,30 +180,19 @@ SCENEGRAPH* Load( char const* aFileName )
|
|||
|
||||
IFSG_FACESET* face = new IFSG_FACESET( *shape );
|
||||
|
||||
// define the vertices of the tetrahedron
|
||||
double SQ2 = sqrt( 0.5 );
|
||||
SGPOINT vert[4];
|
||||
vert[0] = SGPOINT( 1.0, 0.0, -SQ2 );
|
||||
vert[1] = SGPOINT( -1.0, 0.0, -SQ2 );
|
||||
vert[2] = SGPOINT( 0.0, 1.0, SQ2 );
|
||||
vert[3] = SGPOINT( 0.0, -1.0, SQ2 );
|
||||
IFSG_COORDS* cp = new IFSG_COORDS( *face );
|
||||
cp->SetCoordsList( 4, vert );
|
||||
cp->AddCoord( vert[0] );
|
||||
cp->AddCoord( vert[3] );
|
||||
cp->AddCoord( vert[1] );
|
||||
|
||||
// coordinate indices - note: enforce triangles;
|
||||
// in real plugins where it is not necessarily possible
|
||||
// to determine which side a triangle is visible from,
|
||||
// 2 point orders must be specified for each triangle
|
||||
IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face );
|
||||
int cidx[12] = { 0, 3, 1, 0, 2, 3, 1, 3, 2, 0, 1, 2 };
|
||||
coordIdx->SetIndices( 3, cidx );
|
||||
|
||||
// note: track the sets of faces since all faces need to be
|
||||
// instantiated before we can calculate the normals list;
|
||||
// this is due to the need for all vertices to be referenced
|
||||
// in the index lists; however we have a single coordinate
|
||||
// list and 4 associated vertex lists so the requirement is
|
||||
// not met until all faces are instantiated.
|
||||
SGNODE* face1 = face->GetRawPtr();
|
||||
coordIdx->AddIndex( 0 );
|
||||
coordIdx->AddIndex( 1 );
|
||||
coordIdx->AddIndex( 2 );
|
||||
|
||||
// create an appearance; appearances are owned by shapes
|
||||
// magenta
|
||||
|
@ -215,64 +202,99 @@ SCENEGRAPH* Load( char const* aFileName )
|
|||
material->SetAmbient( 0.9 );
|
||||
material->SetShininess( 0.3 );
|
||||
|
||||
// normals
|
||||
IFSG_NORMALS* np = new IFSG_NORMALS( *face );
|
||||
SGVECTOR nval = S3D::CalcTriNorm( vert[0], vert[3], vert[1] );
|
||||
np->AddNormal( nval );
|
||||
np->AddNormal( nval );
|
||||
np->AddNormal( nval );
|
||||
|
||||
//
|
||||
// Shape2
|
||||
// Note: we reuse the IFSG* wrappers to create and manipulate new
|
||||
// data structures.
|
||||
//
|
||||
shape->NewNode( *tx1 );
|
||||
face->NewNode( *shape );
|
||||
face->AddRefNode( *cp );
|
||||
coordIdx->NewNode( *face );
|
||||
coordIdx->SetIndices( 3, &cidx[3] );
|
||||
SGNODE* face2 = face->GetRawPtr();
|
||||
// red
|
||||
cp->NewNode( *face );
|
||||
np->NewNode( *face );
|
||||
// vertices
|
||||
cp->AddCoord( vert[0] );
|
||||
cp->AddCoord( vert[2] );
|
||||
cp->AddCoord( vert[3] );
|
||||
// indices
|
||||
coordIdx->AddIndex( 0 );
|
||||
coordIdx->AddIndex( 1 );
|
||||
coordIdx->AddIndex( 2 );
|
||||
// normals
|
||||
nval = S3D::CalcTriNorm( vert[0], vert[2], vert[3] );
|
||||
np->AddNormal( nval );
|
||||
np->AddNormal( nval );
|
||||
np->AddNormal( nval );
|
||||
// color (red)
|
||||
material->NewNode( *shape );
|
||||
material->SetSpecular( 1.0, 0.0, 0.0 );
|
||||
material->SetDiffuse( 0.9, 0.0, 0.0 );
|
||||
material->SetAmbient( 0.9 );
|
||||
material->SetShininess( 0.3 );
|
||||
|
||||
//
|
||||
// Shape3
|
||||
//
|
||||
shape->NewNode( *tx1 );
|
||||
face->NewNode( *shape );
|
||||
face->AddRefNode( *cp );
|
||||
coordIdx->NewNode( *face );
|
||||
coordIdx->SetIndices( 3, &cidx[6] );
|
||||
SGNODE* face3 = face->GetRawPtr();
|
||||
// green
|
||||
cp->NewNode( *face );
|
||||
np->NewNode( *face );
|
||||
// vertices
|
||||
cp->AddCoord( vert[1] );
|
||||
cp->AddCoord( vert[3] );
|
||||
cp->AddCoord( vert[2] );
|
||||
// indices
|
||||
coordIdx->AddIndex( 0 );
|
||||
coordIdx->AddIndex( 1 );
|
||||
coordIdx->AddIndex( 2 );
|
||||
// normals
|
||||
nval = S3D::CalcTriNorm( vert[1], vert[3], vert[2] );
|
||||
np->AddNormal( nval );
|
||||
np->AddNormal( nval );
|
||||
np->AddNormal( nval );
|
||||
// color (green)
|
||||
material->NewNode( *shape );
|
||||
material->SetSpecular( 0.0, 1.0, 0.0 );
|
||||
material->SetDiffuse( 0.0, 0.9, 0.0 );
|
||||
material->SetAmbient( 0.9 );
|
||||
material->SetShininess( 0.3 );
|
||||
|
||||
//
|
||||
// Shape4
|
||||
//
|
||||
shape->NewNode( *tx1 );
|
||||
face->NewNode( *shape );
|
||||
face->AddRefNode( *cp );
|
||||
coordIdx->NewNode( *face );
|
||||
coordIdx->SetIndices( 3, &cidx[9] );
|
||||
SGNODE* face4 = face->GetRawPtr();
|
||||
// blue
|
||||
cp->NewNode( *face );
|
||||
np->NewNode( *face );
|
||||
// vertices
|
||||
cp->AddCoord( vert[0] );
|
||||
cp->AddCoord( vert[1] );
|
||||
cp->AddCoord( vert[2] );
|
||||
// indices
|
||||
coordIdx->AddIndex( 0 );
|
||||
coordIdx->AddIndex( 1 );
|
||||
coordIdx->AddIndex( 2 );
|
||||
// normals
|
||||
nval = S3D::CalcTriNorm( vert[0], vert[1], vert[2] );
|
||||
np->AddNormal( nval );
|
||||
np->AddNormal( nval );
|
||||
np->AddNormal( nval );
|
||||
// color (blue)
|
||||
material->NewNode( *shape );
|
||||
material->SetSpecular( 0.0, 0.0, 1.0 );
|
||||
material->SetDiffuse( 0.0, 0.0, 0.9 );
|
||||
material->SetAmbient( 0.9 );
|
||||
material->SetShininess( 0.3 );
|
||||
|
||||
// note: now that the faces are instantiated we
|
||||
// can calculate the per-vertex normals
|
||||
SGNODE* np;
|
||||
face->Attach( face1 );
|
||||
face->CalcNormals( &np );
|
||||
|
||||
if( np )
|
||||
{
|
||||
face->Attach( face2 );
|
||||
face->AddRefNode( np );
|
||||
face->Attach( face3 );
|
||||
face->AddRefNode( np );
|
||||
face->Attach( face4 );
|
||||
face->AddRefNode( np );
|
||||
}
|
||||
|
||||
// create a copy of the entire tetrahedron shifted Z+2 and rotated 2/3PI
|
||||
IFSG_TRANSFORM* tx2 = new IFSG_TRANSFORM( tx0->GetRawPtr() );
|
||||
tx2->AddRefNode( *tx1 );
|
||||
|
@ -287,6 +309,7 @@ SCENEGRAPH* Load( char const* aFileName )
|
|||
delete coordIdx;
|
||||
delete material;
|
||||
delete cp;
|
||||
delete np;
|
||||
delete tx0;
|
||||
delete tx1;
|
||||
delete tx2;
|
||||
|
|
|
@ -258,10 +258,11 @@ SCENEGRAPH* Load( char const* aFileName )
|
|||
|
||||
vpcb.Tesselate( NULL );
|
||||
std::vector< double > vertices;
|
||||
std::vector< int > indices;
|
||||
std::vector< int > idxPlane;
|
||||
std::vector< int > idxSide;
|
||||
double thick = outline->GetThickness();
|
||||
|
||||
if( !vpcb.Get3DTriangles( vertices, indices, thick, 0.0 ) )
|
||||
if( !vpcb.Get3DTriangles( vertices, idxPlane, idxSide, thick, 0.0 ) )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
|
@ -271,6 +272,15 @@ SCENEGRAPH* Load( char const* aFileName )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if( ( idxPlane.size() % 3 ) || ( idxSide.size() % 3 ) )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [BUG] index lists are not a multiple of 3 (not a triangle list)\n";
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector< SGPOINT > vlist;
|
||||
size_t nvert = vertices.size() / 3;
|
||||
size_t j = 0;
|
||||
|
@ -279,24 +289,73 @@ SCENEGRAPH* Load( char const* aFileName )
|
|||
vlist.push_back( SGPOINT( vertices[j], vertices[j+1], vertices[j+2] ) );
|
||||
|
||||
// create the intermediate scenegraph
|
||||
IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( true );
|
||||
IFSG_SHAPE* shape = new IFSG_SHAPE( *tx0 );
|
||||
IFSG_FACESET* face = new IFSG_FACESET( *shape );
|
||||
IFSG_COORDS* cp = new IFSG_COORDS( *face );
|
||||
IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( true ); // tx0 = top level Transform
|
||||
IFSG_SHAPE* shape = new IFSG_SHAPE( *tx0 ); // shape will hold (a) all vertices and (b) a local list of normals
|
||||
IFSG_FACESET* face = new IFSG_FACESET( *shape ); // this face shall represent the top and bottom planes
|
||||
IFSG_COORDS* cp = new IFSG_COORDS( *face ); // coordinates for all faces
|
||||
cp->SetCoordsList( nvert, &vlist[0] );
|
||||
IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face );
|
||||
coordIdx->SetIndices( indices.size(), &indices[0] );
|
||||
IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); // coordinate indices for top and bottom planes only
|
||||
coordIdx->SetIndices( idxPlane.size(), &idxPlane[0] );
|
||||
IFSG_NORMALS* norms = new IFSG_NORMALS( *face ); // normals for the top and bottom planes
|
||||
|
||||
if( !face->CalcNormals( NULL ) )
|
||||
// number of TOP (and bottom) vertices
|
||||
j = nvert / 2;
|
||||
|
||||
// set the TOP normals
|
||||
for( size_t i = 0; i < j; ++i )
|
||||
norms->AddNormal( 0.0, 0.0, 1.0 );
|
||||
|
||||
// set the BOTTOM normals
|
||||
for( size_t i = 0; i < j; ++i )
|
||||
norms->AddNormal( 0.0, 0.0, -1.0 );
|
||||
|
||||
// assign a color from the rotating palette
|
||||
SGNODE* modelColor = getColor( *shape );
|
||||
|
||||
// create a second shape describing the vertical walls of the IDF extrusion
|
||||
// using per-vertex-per-face-normals
|
||||
shape->NewNode( *tx0 );
|
||||
shape->AddRefNode( modelColor ); // set the color to be the same as the top/bottom
|
||||
face->NewNode( *shape );
|
||||
cp->NewNode( *face ); // new vertex list
|
||||
norms->NewNode( *face ); // new normals list
|
||||
coordIdx->NewNode( *face ); // new index list
|
||||
|
||||
// populate the new per-face vertex list and its indices and normals
|
||||
std::vector< int >::iterator sI = idxSide.begin();
|
||||
std::vector< int >::iterator eI = idxSide.end();
|
||||
|
||||
size_t sidx = 0; // index to the new coord set
|
||||
SGPOINT p1, p2, p3;
|
||||
SGVECTOR vnorm;
|
||||
|
||||
while( sI != eI )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [INFO] cannot calculate normals\n";
|
||||
#endif
|
||||
p1 = vlist[*sI];
|
||||
cp->AddCoord( p1 );
|
||||
++sI;
|
||||
|
||||
p2 = vlist[*sI];
|
||||
cp->AddCoord( p2 );
|
||||
++sI;
|
||||
|
||||
p3 = vlist[*sI];
|
||||
cp->AddCoord( p3 );
|
||||
++sI;
|
||||
|
||||
vnorm.SetVector( S3D::CalcTriNorm( p1, p2, p3 ) );
|
||||
norms->AddNormal( vnorm );
|
||||
norms->AddNormal( vnorm );
|
||||
norms->AddNormal( vnorm );
|
||||
|
||||
coordIdx->AddIndex( (int)sidx );
|
||||
++sidx;
|
||||
coordIdx->AddIndex( (int)sidx );
|
||||
++sidx;
|
||||
coordIdx->AddIndex( (int)sidx );
|
||||
++sidx;
|
||||
}
|
||||
|
||||
// magenta
|
||||
getColor( *shape );
|
||||
SCENEGRAPH* data = (SCENEGRAPH*)tx0->GetRawPtr();
|
||||
|
||||
// DEBUG: WRITE OUT IDF FILE TO CONFIRM NORMALS
|
||||
|
|
|
@ -1793,10 +1793,12 @@ void VRML_LAYER::SetVertexOffsets( double aXoffset, double aYoffset )
|
|||
|
||||
|
||||
bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
|
||||
std::vector< int > &aIndexList, double aTopZ, double aBotZ )
|
||||
std::vector< int > &aIndexPlane, std::vector< int > &aIndexSide,
|
||||
double aTopZ, double aBotZ )
|
||||
{
|
||||
aVertexList.clear();
|
||||
aIndexList.clear();
|
||||
aIndexPlane.clear();
|
||||
aIndexSide.clear();
|
||||
|
||||
if( ordmap.size() < 3 || outline.empty() )
|
||||
return false;
|
||||
|
@ -1853,20 +1855,24 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
|
|||
std::list< TRIPLET_3D >::const_iterator tbeg = triplets.begin();
|
||||
std::list< TRIPLET_3D >::const_iterator tend = triplets.end();
|
||||
|
||||
std::vector< int > aIndexBot;
|
||||
|
||||
while( tbeg != tend )
|
||||
{
|
||||
// top vertices
|
||||
aIndexList.push_back( (int) tbeg->i1 );
|
||||
aIndexList.push_back( (int) tbeg->i2 );
|
||||
aIndexList.push_back( (int) tbeg->i3 );
|
||||
aIndexPlane.push_back( (int) tbeg->i1 );
|
||||
aIndexPlane.push_back( (int) tbeg->i2 );
|
||||
aIndexPlane.push_back( (int) tbeg->i3 );
|
||||
|
||||
// bottom vertices
|
||||
aIndexList.push_back( (int) ( tbeg->i2 + vsize ) );
|
||||
aIndexList.push_back( (int) ( tbeg->i1 + vsize ) );
|
||||
aIndexList.push_back( (int) ( tbeg->i3 + vsize ) );
|
||||
aIndexBot.push_back( (int) ( tbeg->i2 + vsize ) );
|
||||
aIndexBot.push_back( (int) ( tbeg->i1 + vsize ) );
|
||||
aIndexBot.push_back( (int) ( tbeg->i3 + vsize ) );
|
||||
|
||||
++tbeg;
|
||||
}
|
||||
|
||||
aIndexPlane.insert( aIndexPlane.end(), aIndexBot.begin(), aIndexBot.end() );
|
||||
}
|
||||
|
||||
// compile indices for the walls joining top to bottom
|
||||
|
@ -1902,23 +1908,23 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
|
|||
|
||||
if( !holes_only )
|
||||
{
|
||||
aIndexList.push_back( curPoint );
|
||||
aIndexList.push_back( lastPoint );
|
||||
aIndexList.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexSide.push_back( curPoint );
|
||||
aIndexSide.push_back( lastPoint );
|
||||
aIndexSide.push_back( (int)( curPoint + vsize ) );
|
||||
|
||||
aIndexList.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexList.push_back( lastPoint );
|
||||
aIndexList.push_back( (int)( lastPoint + vsize ) );
|
||||
aIndexSide.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexSide.push_back( lastPoint );
|
||||
aIndexSide.push_back( (int)( lastPoint + vsize ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
aIndexList.push_back( curPoint );
|
||||
aIndexList.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexList.push_back( lastPoint );
|
||||
aIndexSide.push_back( curPoint );
|
||||
aIndexSide.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexSide.push_back( lastPoint );
|
||||
|
||||
aIndexList.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexList.push_back( (int)( lastPoint + vsize ) );
|
||||
aIndexList.push_back( lastPoint );
|
||||
aIndexSide.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexSide.push_back( (int)( lastPoint + vsize ) );
|
||||
aIndexSide.push_back( lastPoint );
|
||||
}
|
||||
|
||||
lastPoint = curPoint;
|
||||
|
@ -1933,23 +1939,23 @@ bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
|
|||
|
||||
if( !holes_only )
|
||||
{
|
||||
aIndexList.push_back( curPoint );
|
||||
aIndexList.push_back( lastPoint );
|
||||
aIndexList.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexSide.push_back( curPoint );
|
||||
aIndexSide.push_back( lastPoint );
|
||||
aIndexSide.push_back( (int)( curPoint + vsize ) );
|
||||
|
||||
aIndexList.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexList.push_back( lastPoint );
|
||||
aIndexList.push_back( (int)( lastPoint + vsize ) );
|
||||
aIndexSide.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexSide.push_back( lastPoint );
|
||||
aIndexSide.push_back( (int)( lastPoint + vsize ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
aIndexList.push_back( curPoint );
|
||||
aIndexList.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexList.push_back( lastPoint );
|
||||
aIndexSide.push_back( curPoint );
|
||||
aIndexSide.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexSide.push_back( lastPoint );
|
||||
|
||||
aIndexList.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexList.push_back( (int)( lastPoint + vsize ) );
|
||||
aIndexList.push_back( lastPoint );
|
||||
aIndexSide.push_back( (int)( curPoint + vsize ) );
|
||||
aIndexSide.push_back( (int)( lastPoint + vsize ) );
|
||||
aIndexSide.push_back( lastPoint );
|
||||
}
|
||||
|
||||
++obeg;
|
||||
|
|
|
@ -463,12 +463,14 @@ public:
|
|||
* triangular vertices which may be used for rendering.
|
||||
*
|
||||
* @param aVertexList will store the vertices
|
||||
* @param aIndexList will store the indices
|
||||
* @param aIndexPlane will store the indices for the top + bottom planes
|
||||
* @param aIndexSide will store the indices for the vertical wall
|
||||
* @param aTopZ is the top plane of the model
|
||||
* @param aBotZ is the bottom plane of the model
|
||||
*/
|
||||
bool Get3DTriangles( std::vector< double >& aVertexList,
|
||||
std::vector< int > &aIndexList, double aTopZ, double aBotZ );
|
||||
std::vector< int > &aIndexPlane, std::vector< int > &aIndexSide,
|
||||
double aTopZ, double aBotZ );
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue