ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SoBox.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SoBox.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 //
28 //
29 /*----------------------------HEPVis----------------------------------------*/
30 /* */
31 /* Node: SoBox */
32 /* Description: Represents the G4Box Geant Geometry entity */
33 /* Author: Joe Boudreau Nov 11 1996 */
34 /* */
35 /*--------------------------------------------------------------------------*/
36 
37 #ifdef G4VIS_BUILD_OI_DRIVER
38 
39 // this :
40 #include "HEPVis/nodes/SoBox.h"
41 
42 #include <assert.h>
43 #include <cmath>
44 
45 #include <Inventor/SbBox.h>
46 #include <Inventor/fields/SoSFFloat.h>
47 #include <Inventor/misc/SoChildList.h>
48 #include <Inventor/nodes/SoSeparator.h>
49 #include <Inventor/nodes/SoCube.h>
50 #include <Inventor/nodes/SoScale.h>
51 #include <Inventor/actions/SoAction.h>
52 #include <Inventor/nodes/SoIndexedFaceSet.h>
53 #include <Inventor/SoPrimitiveVertex.h>
54 #include <Inventor/elements/SoTextureCoordinateElement.h>
55 
56 // This statement is required
57 SO_NODE_SOURCE(SoBox)
58 
59 // Constructor
60 SoBox::SoBox() {
61  // This statement is required
62  SO_NODE_CONSTRUCTOR(SoBox);
63 
64  // Data fields are initialized like this:
65  SO_NODE_ADD_FIELD(fDx, (1.0));
66  SO_NODE_ADD_FIELD(fDy, (1.0));
67  SO_NODE_ADD_FIELD(fDz, (1.0));
68  SO_NODE_ADD_FIELD(alternateRep, (NULL));
69  children = new SoChildList(this);
70 }
71 
72 // Destructor
73 SoBox::~SoBox() {
74  delete children;
75 }
76 
77 
78 // initClass
79 void SoBox::initClass(){
80  // This statement is required.
81  SO_NODE_INIT_CLASS(SoBox,SoShape,"Shape");
82 }
83 
84 
85 // generatePrimitives
86 void SoBox::generatePrimitives(SoAction *action) {
87  // This variable is used to store each vertex
88  SoPrimitiveVertex pv;
89 
90  // Access the stat from the action
91  SoState *state = action->getState();
92 
93  // See if we have to use a texture coordinate function,
94  // rather than generating explicit texture coordinates.
95  SbBool useTexFunction=
96  (SoTextureCoordinateElement::getType(state) ==
97  SoTextureCoordinateElement::FUNCTION);
98 
99  // If we need to generate texture coordinates with a function,
100  // we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
101  // set up the coordinates directly.
102  const SoTextureCoordinateElement *tce = NULL;
103  SbVec4f texCoord;
104  if (useTexFunction) {
105  tce = SoTextureCoordinateElement::getInstance(state);
106  }
107  else {
108  texCoord[2] = 0.0;
109  texCoord[3] = 1.0;
110  }
111  SbVec3f point, normal;
112 
113 
115  //----------------------------------------
116 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
117  point.setValue(x,y,z); \
118  normal.setValue(nx,ny,nz); \
119  if (useTexFunction) { \
120  texCoord=tce->get(point,normal); \
121  } \
122  else { \
123  texCoord[0]=s; \
124  texCoord[1]=t; \
125  } \
126  pv.setPoint(point); \
127  pv.setNormal(normal); \
128  pv.setTextureCoords(texCoord); \
129  shapeVertex(&pv);
130  //----------------------------------------
132 
133  const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
134  int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, //z back.
135  4,5,6,7, SO_END_FACE_INDEX, //z front.
136  0,1,5,4, SO_END_FACE_INDEX, //y up.
137  1,2,6,5, SO_END_FACE_INDEX, //x left.
138  2,3,7,6, SO_END_FACE_INDEX, //y down.
139  3,0,4,7, SO_END_FACE_INDEX}; //x right.
140 
141 
142  // points for the eight vertices
143  float points[NPOINTS][3];
144  points[0][0] = fDx.getValue();
145  points[0][1] = fDy.getValue();
146  points[0][2] = -fDz.getValue();
147 
148  points[1][0] = -fDx.getValue();
149  points[1][1] = fDy.getValue();
150  points[1][2] = -fDz.getValue();
151 
152  points[2][0] = -fDx.getValue();
153  points[2][1] = -fDy.getValue();
154  points[2][2] = -fDz.getValue();
155 
156  points[3][0] = fDx.getValue();
157  points[3][1] = -fDy.getValue();
158  points[3][2] = -fDz.getValue();
159 
160  points[4][0] = fDx.getValue();
161  points[4][1] = fDy.getValue();
162  points[4][2] = fDz.getValue();
163 
164  points[5][0] = -fDx.getValue();
165  points[5][1] = fDy.getValue();
166  points[5][2] = fDz.getValue();
167 
168  points[6][0] = -fDx.getValue();
169  points[6][1] = -fDy.getValue();
170  points[6][2] = fDz.getValue();
171 
172  points[7][0] = fDx.getValue();
173  points[7][1] = -fDy.getValue();
174  points[7][2] = fDz.getValue();
175 
176  float normals[NFACES][3];
177  //z back.
178  normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
179  //z front.
180  normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
181  //y up.
182  normals[2][0] = 0 ; normals[2][1] = 1; normals [2][2] = 0;
183  //x left.
184  normals[3][0] = -1 ; normals[3][1] = 0; normals [3][2] = 0;
185  //y down.
186  normals[4][0] = 0 ; normals[4][1] = -1; normals [4][2] = 0;
187  //x right.
188  normals[5][0] = 1 ; normals[5][1] = 0; normals [5][2] = 0;
189 
190  float x,y,z;
191  int index;
192  for (int nf=0;nf<NFACES;nf++) {
193  beginShape(action,TRIANGLE_FAN);
194  index = indices[nf * 5];
195  x = points[index][0];
196  y = points[index][1];
197  z = points[index][2];
198  GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
199  index = indices[nf * 5 + 1];
200  x = points[index][0];
201  y = points[index][1];
202  z = points[index][2];
203  GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
204  index = indices[nf * 5 + 2];
205  x = points[index][0];
206  y = points[index][1];
207  z = points[index][2];
208  GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
209  index = indices[nf * 5 + 3];
210  x = points[index][0];
211  y = points[index][1];
212  z = points[index][2];
213  GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
214  endShape();
215  }
216 }
217 
218 // getChildren
219 SoChildList *SoBox::getChildren() const {
220  return children;
221 }
222 
223 
224 // computeBBox
225 void SoBox::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
226  SbVec3f vmin(-fDx.getValue(),-fDy.getValue(),-fDz.getValue()),
227  vmax( fDx.getValue(), fDy.getValue(), fDz.getValue());
228  center.setValue(0,0,0);
229  box.setBounds(vmin,vmax);
230 }
231 
232 
233 
234 
235 // updateChildren
236 void SoBox::updateChildren() {
237 
238 
239  // Redraw the G4Box....
240 
241  assert(children->getLength()==1);
242  SoSeparator *sep = (SoSeparator *) ( *children)[0];
243  SoScale *scale = (SoScale *)( sep->getChild(0));
244  //SoCube *cube = (SoCube *)( sep->getChild(1));
245  scale->scaleFactor.setValue(fDx.getValue(), fDy.getValue(), fDz.getValue());
246 }
247 
248 // generateChildren
250 
251  // A box consists of a set of scale factors and a
252  // cube.
253 
254  assert(children->getLength() ==0);
255  SoSeparator *sep = new SoSeparator();
256  SoScale *scale = new SoScale();
257  SoCube *cube = new SoCube();
258 
259  sep->addChild(scale);
260  sep->addChild(cube);
261  children->append(sep);
262 }
263 
264 // generateAlternateRep
266 
267  // This routine sets the alternate representation to the child
268  // list of this mode.
269 
270  if (children->getLength() == 0) generateChildren();
271  updateChildren();
272  alternateRep.setValue((SoSeparator *) ( *children)[0]);
273 }
274 
275 // clearAlternateRep
277  alternateRep.setValue(NULL);
278 }
279 
280 #endif