00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifdef G4VIS_BUILD_OI_DRIVER
00039
00040
00041 #include "HEPVis/nodes/SoBox.h"
00042
00043 #include <assert.h>
00044 #include <cmath>
00045
00046 #include <Inventor/SbBox.h>
00047 #include <Inventor/fields/SoSFFloat.h>
00048 #include <Inventor/misc/SoChildList.h>
00049 #include <Inventor/nodes/SoSeparator.h>
00050 #include <Inventor/nodes/SoCube.h>
00051 #include <Inventor/nodes/SoScale.h>
00052 #include <Inventor/actions/SoAction.h>
00053 #include <Inventor/nodes/SoIndexedFaceSet.h>
00054 #include <Inventor/SoPrimitiveVertex.h>
00055 #include <Inventor/elements/SoTextureCoordinateElement.h>
00056
00057
00058 SO_NODE_SOURCE(SoBox)
00059
00060
00061 SoBox::SoBox() {
00062
00063 SO_NODE_CONSTRUCTOR(SoBox);
00064
00065
00066 SO_NODE_ADD_FIELD(fDx, (1.0));
00067 SO_NODE_ADD_FIELD(fDy, (1.0));
00068 SO_NODE_ADD_FIELD(fDz, (1.0));
00069 SO_NODE_ADD_FIELD(alternateRep, (NULL));
00070 children = new SoChildList(this);
00071 }
00072
00073
00074 SoBox::~SoBox() {
00075 delete children;
00076 }
00077
00078
00079
00080 void SoBox::initClass(){
00081
00082 SO_NODE_INIT_CLASS(SoBox,SoShape,"Shape");
00083 }
00084
00085
00086
00087 void SoBox::generatePrimitives(SoAction *action) {
00088
00089 SoPrimitiveVertex pv;
00090
00091
00092 SoState *state = action->getState();
00093
00094
00095
00096 SbBool useTexFunction=
00097 (SoTextureCoordinateElement::getType(state) ==
00098 SoTextureCoordinateElement::FUNCTION);
00099
00100
00101
00102
00103 const SoTextureCoordinateElement *tce = NULL;
00104 SbVec4f texCoord;
00105 if (useTexFunction) {
00106 tce = SoTextureCoordinateElement::getInstance(state);
00107 }
00108 else {
00109 texCoord[2] = 0.0;
00110 texCoord[3] = 1.0;
00111 }
00112 SbVec3f point, normal;
00113
00114
00116
00117 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
00118 point.setValue(x,y,z); \
00119 normal.setValue(nx,ny,nz); \
00120 if (useTexFunction) { \
00121 texCoord=tce->get(point,normal); \
00122 } \
00123 else { \
00124 texCoord[0]=s; \
00125 texCoord[1]=t; \
00126 } \
00127 pv.setPoint(point); \
00128 pv.setNormal(normal); \
00129 pv.setTextureCoords(texCoord); \
00130 shapeVertex(&pv);
00131
00133
00134 const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
00135 int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,
00136 4,5,6,7, SO_END_FACE_INDEX,
00137 0,1,5,4, SO_END_FACE_INDEX,
00138 1,2,6,5, SO_END_FACE_INDEX,
00139 2,3,7,6, SO_END_FACE_INDEX,
00140 3,0,4,7, SO_END_FACE_INDEX};
00141
00142
00143
00144 float points[NPOINTS][3];
00145 points[0][0] = fDx.getValue();
00146 points[0][1] = fDy.getValue();
00147 points[0][2] = -fDz.getValue();
00148
00149 points[1][0] = -fDx.getValue();
00150 points[1][1] = fDy.getValue();
00151 points[1][2] = -fDz.getValue();
00152
00153 points[2][0] = -fDx.getValue();
00154 points[2][1] = -fDy.getValue();
00155 points[2][2] = -fDz.getValue();
00156
00157 points[3][0] = fDx.getValue();
00158 points[3][1] = -fDy.getValue();
00159 points[3][2] = -fDz.getValue();
00160
00161 points[4][0] = fDx.getValue();
00162 points[4][1] = fDy.getValue();
00163 points[4][2] = fDz.getValue();
00164
00165 points[5][0] = -fDx.getValue();
00166 points[5][1] = fDy.getValue();
00167 points[5][2] = fDz.getValue();
00168
00169 points[6][0] = -fDx.getValue();
00170 points[6][1] = -fDy.getValue();
00171 points[6][2] = fDz.getValue();
00172
00173 points[7][0] = fDx.getValue();
00174 points[7][1] = -fDy.getValue();
00175 points[7][2] = fDz.getValue();
00176
00177 float normals[NFACES][3];
00178
00179 normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
00180
00181 normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
00182
00183 normals[2][0] = 0 ; normals[2][1] = 1; normals [2][2] = 0;
00184
00185 normals[3][0] = -1 ; normals[3][1] = 0; normals [3][2] = 0;
00186
00187 normals[4][0] = 0 ; normals[4][1] = -1; normals [4][2] = 0;
00188
00189 normals[5][0] = 1 ; normals[5][1] = 0; normals [5][2] = 0;
00190
00191 float x,y,z;
00192 int index;
00193 for (int nf=0;nf<NFACES;nf++) {
00194 beginShape(action,TRIANGLE_FAN);
00195 index = indices[nf * 5];
00196 x = points[index][0];
00197 y = points[index][1];
00198 z = points[index][2];
00199 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00200 index = indices[nf * 5 + 1];
00201 x = points[index][0];
00202 y = points[index][1];
00203 z = points[index][2];
00204 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00205 index = indices[nf * 5 + 2];
00206 x = points[index][0];
00207 y = points[index][1];
00208 z = points[index][2];
00209 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00210 index = indices[nf * 5 + 3];
00211 x = points[index][0];
00212 y = points[index][1];
00213 z = points[index][2];
00214 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00215 endShape();
00216 }
00217 }
00218
00219
00220 SoChildList *SoBox::getChildren() const {
00221 return children;
00222 }
00223
00224
00225
00226 void SoBox::computeBBox(SoAction *, SbBox3f &box, SbVec3f ¢er ){
00227 SbVec3f vmin(-fDx.getValue(),-fDy.getValue(),-fDz.getValue()),
00228 vmax( fDx.getValue(), fDy.getValue(), fDz.getValue());
00229 center.setValue(0,0,0);
00230 box.setBounds(vmin,vmax);
00231 }
00232
00233
00234
00235
00236
00237 void SoBox::updateChildren() {
00238
00239
00240
00241
00242 assert(children->getLength()==1);
00243 SoSeparator *sep = (SoSeparator *) ( *children)[0];
00244 SoScale *scale = (SoScale *)( sep->getChild(0));
00245
00246 scale->scaleFactor.setValue(fDx.getValue(), fDy.getValue(), fDz.getValue());
00247 }
00248
00249
00250 void SoBox::generateChildren() {
00251
00252
00253
00254
00255 assert(children->getLength() ==0);
00256 SoSeparator *sep = new SoSeparator();
00257 SoScale *scale = new SoScale();
00258 SoCube *cube = new SoCube();
00259
00260 sep->addChild(scale);
00261 sep->addChild(cube);
00262 children->append(sep);
00263 }
00264
00265
00266 void SoBox::generateAlternateRep() {
00267
00268
00269
00270
00271 if (children->getLength() == 0) generateChildren();
00272 updateChildren();
00273 alternateRep.setValue((SoSeparator *) ( *children)[0]);
00274 }
00275
00276
00277 void SoBox::clearAlternateRep() {
00278 alternateRep.setValue(NULL);
00279 }
00280
00281 #endif