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