39 #ifdef G4VIS_BUILD_OI_DRIVER 
   46 #include <Inventor/SbBox.h> 
   47 #include <Inventor/actions/SoGLRenderAction.h> 
   48 #include <Inventor/actions/SoAction.h> 
   49 #include <Inventor/fields/SoSFFloat.h> 
   50 #include <Inventor/misc/SoChildList.h> 
   51 #include <Inventor/nodes/SoSeparator.h> 
   52 #include <Inventor/nodes/SoIndexedFaceSet.h> 
   53 #include <Inventor/nodes/SoNormal.h> 
   54 #include <Inventor/nodes/SoCoordinate3.h> 
   55 #include <Inventor/nodes/SoNormalBinding.h> 
   56 #include <Inventor/SoPrimitiveVertex.h> 
   57 #include <Inventor/elements/SoTextureCoordinateElement.h> 
   67   SO_NODE_CONSTRUCTOR(SoTrap);
 
   70   SO_NODE_ADD_FIELD(pDz,                 (1.0));
 
   71   SO_NODE_ADD_FIELD(pTheta,              (0.0));
 
   72   SO_NODE_ADD_FIELD(pPhi,                (0.0));
 
   73   SO_NODE_ADD_FIELD(pDy1,                (1.0));
 
   74   SO_NODE_ADD_FIELD(pDx1,                (1.0));
 
   75   SO_NODE_ADD_FIELD(pDx2,                (1.0));
 
   76   SO_NODE_ADD_FIELD(pDy2,                (1.0));
 
   77   SO_NODE_ADD_FIELD(pDx3,                (1.0));
 
   78   SO_NODE_ADD_FIELD(pDx4,                (1.0));
 
   79   SO_NODE_ADD_FIELD(pAlp1,               (0.0));
 
   80   SO_NODE_ADD_FIELD(pAlp2,               (0.0));
 
   81   SO_NODE_ADD_FIELD(alternateRep,        (NULL));
 
   82   children = 
new SoChildList(
this);
 
   94   SO_NODE_INIT_CLASS(SoTrap,SoShape,
"Shape");
 
  101   SoPrimitiveVertex pv;
 
  104   SoState *state = action->getState();
 
  108   SbBool useTexFunction=
 
  109     (SoTextureCoordinateElement::getType(state) == 
 
  110      SoTextureCoordinateElement::FUNCTION);
 
  115   const SoTextureCoordinateElement *tce = NULL;
 
  117   if (useTexFunction) {
 
  118     tce = SoTextureCoordinateElement::getInstance(state);
 
  124   SbVec3f point, normal;
 
  129 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz)  \ 
  130   point.setValue(x,y,z);                   \ 
  131   normal.setValue(nx,ny,nz);               \ 
  132   if (useTexFunction) {                    \ 
  133     texCoord=tce->get(point,normal);       \ 
  139   pv.setPoint(point);                      \ 
  140   pv.setNormal(normal);                    \ 
  141   pv.setTextureCoords(texCoord);           \ 
  146   const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
 
  147   int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,  
 
  148                4,5,6,7, SO_END_FACE_INDEX,  
 
  149                0,1,5,4, SO_END_FACE_INDEX,  
 
  150                1,2,6,5, SO_END_FACE_INDEX,  
 
  151                2,3,7,6, SO_END_FACE_INDEX,  
 
  152                3,0,4,7, SO_END_FACE_INDEX}; 
 
  160   float points[NPOINTS][3];
 
  161   points[0][0] =  
pDx2.getValue()+
pDy1.getValue()*Talp1;
 
  162   points[0][1] =  
pDy1.getValue();
 
  163   points[0][2] = -
pDz.getValue();
 
  165   points[1][0] = -
pDx2.getValue()+
pDy1.getValue()*Talp1;
 
  166   points[1][1] =  
pDy1.getValue();
 
  167   points[1][2] = -
pDz.getValue();
 
  169   points[2][0] = -
pDx1.getValue()-
pDy1.getValue()*Talp1;
 
  170   points[2][1] = -
pDy1.getValue();
 
  171   points[2][2] = -
pDz.getValue();
 
  173   points[3][0] =  
pDx1.getValue()-
pDy1.getValue()*Talp1;
 
  174   points[3][1] = -
pDy1.getValue();
 
  175   points[3][2] = -
pDz.getValue();
 
  177   points[4][0] =  
pDx4.getValue()+
pDy2.getValue()*Talp2;
 
  178   points[4][1] =  
pDy2.getValue();
 
  179   points[4][2] =  
pDz.getValue();
 
  181   points[5][0] = -
pDx4.getValue()+
pDy2.getValue()*Talp2;
 
  182   points[5][1] =  
pDy2.getValue();
 
  183   points[5][2] =  
pDz.getValue();
 
  185   points[6][0] = -
pDx3.getValue()-
pDy2.getValue()*Talp2;
 
  186   points[6][1] = -
pDy2.getValue();
 
  187   points[6][2] =  
pDz.getValue();
 
  189   points[7][0] =  
pDx3.getValue()-
pDy2.getValue()*Talp2;
 
  190   points[7][1] = -
pDy2.getValue();
 
  191   points[7][2] =  
pDz.getValue();
 
  195     points[i][0] -= 
pDz.getValue()*TthetaCphi;
 
  196     points[i][1] -= 
pDz.getValue()*TthetaSphi;
 
  199     points[i][0] += 
pDz.getValue()*TthetaCphi;
 
  200     points[i][1] += 
pDz.getValue()*TthetaSphi;
 
  203   SbVec3f normals[NFACES];
 
  205   for (nf=0;nf<NFACES;nf++) {
 
  206     int j0 = indices[5*nf + 0];
 
  207     int j1 = indices[5*nf + 1];
 
  208     int j2 = indices[5*nf + 2];
 
  209     SbVec3f p0(points[j0][0],points[j0][1],points[j0][2]); 
 
  210     SbVec3f p1(points[j1][0],points[j1][1],points[j1][2]); 
 
  211     SbVec3f p2(points[j2][0],points[j2][1],points[j2][2]); 
 
  212     normals[nf] = (p1-p0).cross(p2-p0);
 
  213     normals[nf].normalize();
 
  218   for (nf=0;nf<NFACES;nf++) {
 
  219     beginShape(action,TRIANGLE_FAN);
 
  220     index = indices[nf * 5];   
 
  221     x = points[
index][0];
 
  222     y = points[
index][1];
 
  223     z = points[
index][2];
 
  224     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
 
  225     index = indices[nf * 5 + 1];   
 
  226     x = points[
index][0];
 
  227     y = points[
index][1];
 
  228     z = points[
index][2];
 
  229     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
 
  230     index = indices[nf * 5 + 2];   
 
  231     x = points[
index][0];
 
  232     y = points[
index][1];
 
  233     z = points[
index][2];
 
  234     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
 
  235     index = indices[nf * 5 + 3];   
 
  236     x = points[
index][0];
 
  237     y = points[
index][1];
 
  238     z = points[
index][2];
 
  239     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
 
  252   float pDx= 
pDx1.getValue(),pDy=
pDy1.getValue();
 
  254   if (
pDx2.getValue() > pDx) pDx = 
pDx2.getValue(); 
 
  255   if (
pDx3.getValue() > pDx) pDx = 
pDx3.getValue(); 
 
  256   if (
pDx4.getValue() > pDx) pDx = 
pDx4.getValue(); 
 
  257   if (
pDy2.getValue() > pDy) pDy = 
pDy2.getValue(); 
 
  262   if (Xalp< Xalp2) Xalp=Xalp2;
 
  263   pDx += 
FFABS(TthetaCphi*
pDz.getValue());
 
  265   pDy += 
FFABS(TthetaSphi*
pDz.getValue());  
 
  268   center.setValue(0,0,0);
 
  269   box.setBounds(SbVec3f(-pDx,-pDy,-
pDz.getValue()),
 
  270       SbVec3f( pDx, pDy, 
pDz.getValue()));
 
  277 void SoTrap::updateChildren() {
 
  282   assert(children->getLength()==1);
 
  283   SoSeparator       *sep                = (SoSeparator *)  ( *children)[0];
 
  284   SoCoordinate3     *theCoordinates     = (SoCoordinate3 *)      ( sep->getChild(0));
 
  285   SoNormal          *theNormals         = (SoNormal *)           ( sep->getChild(1)); 
 
  286   SoNormalBinding   *theNormalBinding   = (SoNormalBinding *)    ( sep->getChild(2));
 
  287   SoIndexedFaceSet  *theFaceSet         = (SoIndexedFaceSet *)   ( sep->getChild(3));
 
  289   const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
 
  290   float points[NPOINTS][3];
 
  297   indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, 
 
  298                      4,5,6,7, SO_END_FACE_INDEX, 
 
  299                      0,1,5,4, SO_END_FACE_INDEX, 
 
  300                      1,2,6,5, SO_END_FACE_INDEX,
 
  301                      2,3,7,6, SO_END_FACE_INDEX,
 
  302                      3,0,4,7, SO_END_FACE_INDEX};
 
  311   points[0][0] =  
pDx2.getValue()+
pDy1.getValue()*Talp1;
 
  312   points[0][1] =  
pDy1.getValue();
 
  313   points[0][2] = -
pDz.getValue();
 
  315   points[1][0] = -
pDx2.getValue()+
pDy1.getValue()*Talp1;
 
  316   points[1][1] =  
pDy1.getValue();
 
  317   points[1][2] = -
pDz.getValue();
 
  319   points[2][0] = -
pDx1.getValue()-
pDy1.getValue()*Talp1;
 
  320   points[2][1] = -
pDy1.getValue();
 
  321   points[2][2] = -
pDz.getValue();
 
  323   points[3][0] =  
pDx1.getValue()-
pDy1.getValue()*Talp1;
 
  324   points[3][1] = -
pDy1.getValue();
 
  325   points[3][2] = -
pDz.getValue();
 
  327   points[4][0] =  
pDx4.getValue()+
pDy2.getValue()*Talp2;
 
  328   points[4][1] =  
pDy2.getValue();
 
  329   points[4][2] =  
pDz.getValue();
 
  331   points[5][0] = -
pDx4.getValue()+
pDy2.getValue()*Talp2;
 
  332   points[5][1] =  
pDy2.getValue();
 
  333   points[5][2] =  
pDz.getValue();
 
  335   points[6][0] = -
pDx3.getValue()-
pDy2.getValue()*Talp2;
 
  336   points[6][1] = -
pDy2.getValue();
 
  337   points[6][2] =  
pDz.getValue();
 
  339   points[7][0] =  
pDx3.getValue()-
pDy2.getValue()*Talp2;
 
  340   points[7][1] = -
pDy2.getValue();
 
  341   points[7][2] =  
pDz.getValue();
 
  345     points[i][0] -= 
pDz.getValue()*TthetaCphi;
 
  346     points[i][1] -= 
pDz.getValue()*TthetaSphi;
 
  349     points[i][0] += 
pDz.getValue()*TthetaCphi;
 
  350     points[i][1] += 
pDz.getValue()*TthetaSphi;
 
  353   for (
int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
 
  354   theFaceSet->coordIndex.setValues(0,NINDICES,indices);
 
  355   theNormals->vector.deleteValues(0);
 
  356   theNormals->vector.insertSpace(0,6);
 
  357   for (
int n=0;
n<6;
n++) {
 
  358     int i0 = 5*
n+0,i1=5*
n+1,i2=5*
n+2;
 
  359     int j0 = theFaceSet->coordIndex[i0];
 
  360     int j1 = theFaceSet->coordIndex[i1];
 
  361     int j2 = theFaceSet->coordIndex[i2];
 
  362     SbVec3f p0= theCoordinates->point[j0]; 
 
  363     SbVec3f p1= theCoordinates->point[j1]; 
 
  364     SbVec3f p2= theCoordinates->point[j2]; 
 
  365     SbVec3f normal = (p1-p0).cross(p2-p0);
 
  367     theNormals->vector.set1Value(
n,normal);
 
  369   theNormalBinding->value=SoNormalBinding::PER_FACE;
 
  373 void SoTrap::generateChildren() {
 
  380   assert(children->getLength() ==0);
 
  381   SoSeparator      *sep              = 
new SoSeparator(); 
 
  382   SoCoordinate3    *theCoordinates   = 
new SoCoordinate3();
 
  383   SoNormal         *theNormals       = 
new SoNormal(); 
 
  384   SoNormalBinding  *theNormalBinding = 
new SoNormalBinding();
 
  385   SoIndexedFaceSet *theFaceSet       = 
new SoIndexedFaceSet();
 
  389   sep->addChild(theCoordinates);
 
  390   sep->addChild(theNormals);
 
  391   sep->addChild(theNormalBinding);
 
  392   sep->addChild(theFaceSet);
 
  393   children->append(sep);
 
  402   if (children->getLength() == 0) generateChildren();
 
SoSFFloat pDy2
Half-length along y of the face at +pDz. 
 
SoSFFloat pDz
half-length along Z 
 
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er)
compute bounding Box, required 
 
virtual SoChildList * getChildren() const 
GetChildList, required whenever the class has hidden children. 
 
SoSFFloat pDy1
Half-length along y of the face at -pDz. 
 
virtual void generateAlternateRep()
 
SoSFNode alternateRep
Alternate rep - required. 
 
SoSFFloat pDx3
Half-length along x of the side at y=-pDy2 of the face at +pDz. 
 
virtual void generatePrimitives(SoAction *action)
Generate Primitives, required. 
 
SoSFFloat pDx2
Half-length along x of the side at y=+pDy1 of the face at -pDz. 
 
virtual ~SoTrap()
Destructor, required. 
 
SoSFFloat pTheta
Polar angle of the line joining the centres of the faces at -/+pDz. 
 
virtual void clearAlternateRep()
We better be able to clear it, too! 
 
SoSFFloat pDx4
Half-length along x of the side at y=+pDy2 of the face at +pDz. 
 
static void initClass()
Class Initializer, required. 
 
SoSFFloat pDx1
Half-length along x of the side at y=-pDy1 of the face at -pDz.