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 #include <assert.h>
00041 #include <cmath>
00042
00043 #include <Inventor/SbBox.h>
00044 #include <Inventor/actions/SoAction.h>
00045 #include <Inventor/fields/SoSFFloat.h>
00046 #include <Inventor/misc/SoChildList.h>
00047 #include <Inventor/nodes/SoSeparator.h>
00048 #include <Inventor/nodes/SoIndexedFaceSet.h>
00049 #include <Inventor/nodes/SoNormal.h>
00050 #include <Inventor/nodes/SoCoordinate3.h>
00051 #include <Inventor/nodes/SoNormalBinding.h>
00052 #include <Inventor/SoPrimitiveVertex.h>
00053 #include <Inventor/elements/SoTextureCoordinateElement.h>
00054
00055 #include "HEPVis/SbMath.h"
00056 #include "HEPVis/nodes/SoTrd.h"
00057
00058
00059 SO_NODE_SOURCE(SoTrd)
00060
00061
00062 void SoTrd::initClass(){
00063 SO_NODE_INIT_CLASS(SoTrd,SoShape,"Shape");
00064 }
00065
00066 SoTrd::SoTrd() {
00067
00068 SO_NODE_CONSTRUCTOR(SoTrd);
00069
00070 SO_NODE_ADD_FIELD(fDx1,(1.0));
00071 SO_NODE_ADD_FIELD(fDx2,(1.0));
00072 SO_NODE_ADD_FIELD(fDy1,(1.0));
00073 SO_NODE_ADD_FIELD(fDy2,(1.0));
00074 SO_NODE_ADD_FIELD(fDz,(1.0));
00075 SO_NODE_ADD_FIELD(alternateRep,(NULL));
00076 children = new SoChildList(this);
00077 }
00078
00079 SoTrd::~SoTrd() {
00080 delete children;
00081 }
00082
00083 void SoTrd::generatePrimitives(SoAction *action) {
00084
00085 SoPrimitiveVertex pv;
00086
00087
00088 SoState *state = action->getState();
00089
00090
00091
00092 SbBool useTexFunction=
00093 (SoTextureCoordinateElement::getType(state) ==
00094 SoTextureCoordinateElement::FUNCTION);
00095
00096
00097
00098
00099 const SoTextureCoordinateElement *tce = NULL;
00100 SbVec4f texCoord;
00101 if (useTexFunction) {
00102 tce = SoTextureCoordinateElement::getInstance(state);
00103 }
00104 else {
00105 texCoord[2] = 0.0;
00106 texCoord[3] = 1.0;
00107 }
00108 SbVec3f point, normal;
00109
00110
00112
00113 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
00114 point.setValue(x,y,z); \
00115 normal.setValue(nx,ny,nz); \
00116 if (useTexFunction) { \
00117 texCoord=tce->get(point,normal); \
00118 } \
00119 else { \
00120 texCoord[0]=s; \
00121 texCoord[1]=t; \
00122 } \
00123 pv.setPoint(point); \
00124 pv.setNormal(normal); \
00125 pv.setTextureCoords(texCoord); \
00126 shapeVertex(&pv);
00127
00129
00130 const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
00131 int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,
00132 4,5,6,7, SO_END_FACE_INDEX,
00133 0,1,5,4, SO_END_FACE_INDEX,
00134 1,2,6,5, SO_END_FACE_INDEX,
00135 2,3,7,6, SO_END_FACE_INDEX,
00136 3,0,4,7, SO_END_FACE_INDEX};
00137
00138
00139
00140 float points[NPOINTS][3];
00141 points[0][0] = fDx1.getValue();
00142 points[0][1] = fDy1.getValue();
00143 points[0][2] = -fDz.getValue();
00144
00145 points[1][0] = -fDx1.getValue();
00146 points[1][1] = fDy1.getValue();
00147 points[1][2] = -fDz.getValue();
00148
00149 points[2][0] = -fDx1.getValue();
00150 points[2][1] = -fDy1.getValue();
00151 points[2][2] = -fDz.getValue();
00152
00153 points[3][0] = fDx1.getValue();
00154 points[3][1] = -fDy1.getValue();
00155 points[3][2] = -fDz.getValue();
00156
00157 points[4][0] = fDx2.getValue();
00158 points[4][1] = fDy2.getValue();
00159 points[4][2] = fDz.getValue();
00160
00161 points[5][0] = -fDx2.getValue();
00162 points[5][1] = fDy2.getValue();
00163 points[5][2] = fDz.getValue();
00164
00165 points[6][0] = -fDx2.getValue();
00166 points[6][1] = -fDy2.getValue();
00167 points[6][2] = fDz.getValue();
00168
00169 points[7][0] = fDx2.getValue();
00170 points[7][1] = -fDy2.getValue();
00171 points[7][2] = fDz.getValue();
00172
00173 float t1 = FATAN((fDx2.getValue()-fDx1.getValue())/(2*fDz.getValue()));
00174 float t2 = FATAN((fDy2.getValue()-fDy1.getValue())/(2*fDz.getValue()));
00175 float st1 = FSIN(t1);
00176 float st2 = FSIN(t2);
00177 float ct1 = FCOS(t1);
00178 float ct2 = FCOS(t2);
00179
00180 float normals[NFACES][3];
00181
00182 normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
00183
00184 normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
00185
00186 normals[2][0] = 0 ; normals[2][1] = ct2; normals [2][2] = -st2;
00187
00188 normals[3][0] = -ct1; normals[3][1] = 0; normals [3][2] = -st1;
00189
00190 normals[4][0] = 0 ; normals[4][1] = -ct2; normals [4][2] = -st2;
00191
00192 normals[5][0] = ct1; normals[5][1] = 0; normals [5][2] = -st1;
00193
00194 float x,y,z;
00195 int index;
00196 for (int nf=0;nf<NFACES;nf++) {
00197 beginShape(action,TRIANGLE_FAN);
00198 index = indices[nf * 5];
00199 x = points[index][0];
00200 y = points[index][1];
00201 z = points[index][2];
00202 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00203 index = indices[nf * 5 + 1];
00204 x = points[index][0];
00205 y = points[index][1];
00206 z = points[index][2];
00207 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00208 index = indices[nf * 5 + 2];
00209 x = points[index][0];
00210 y = points[index][1];
00211 z = points[index][2];
00212 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00213 index = indices[nf * 5 + 3];
00214 x = points[index][0];
00215 y = points[index][1];
00216 z = points[index][2];
00217 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00218 endShape();
00219 }
00220 }
00221
00222
00223 SoChildList *SoTrd::getChildren() const {
00224 return children;
00225 }
00226
00227
00228
00229 void SoTrd::computeBBox(SoAction *, SbBox3f &box, SbVec3f ¢er ){
00230 float fDx= fDx1.getValue(),fDy=fDy1.getValue();
00231
00232 if (fDx2.getValue() > fDx) fDx = fDx2.getValue();
00233 if (fDy2.getValue() > fDy) fDy = fDy2.getValue();
00234
00235 SbVec3f vmin(-fDx,-fDy,-fDz.getValue()),
00236 vmax( fDx, fDy, fDz.getValue());
00237
00238 center.setValue(0,0,0);
00239 box.setBounds(vmin,vmax);
00240 }
00241
00242
00243
00244
00245
00246 void SoTrd::updateChildren() {
00247
00248
00249
00250
00251 assert(children->getLength()==1);
00252 SoSeparator *sep = (SoSeparator *) ( *children)[0];
00253 SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
00254 SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
00255 SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
00256 SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
00257
00258 const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
00259 float points[NPOINTS][3];
00260 float normals[NFACES][3]= {{0,0,-1}, {0,0,1}, {0,1,0}, {-1, 0, 0}, {0, -1, 0}, {1,0,0}};
00261
00262
00263 #ifdef INVENTOR2_0
00264 static long
00265 #else
00266 static int32_t
00267 #endif
00268 indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,
00269 4,5,6,7, SO_END_FACE_INDEX,
00270 0,1,5,4, SO_END_FACE_INDEX,
00271 1,2,6,5, SO_END_FACE_INDEX,
00272 2,3,7,6, SO_END_FACE_INDEX,
00273 3,0,4,7, SO_END_FACE_INDEX};
00274
00275
00276
00277 points[0][0] = fDx1.getValue(); points[0][1] = fDy1.getValue(); points[0][2] = -fDz.getValue();
00278 points[1][0] = -fDx1.getValue(); points[1][1] = fDy1.getValue(); points[1][2] = -fDz.getValue();
00279 points[2][0] = -fDx1.getValue(); points[2][1] = -fDy1.getValue(); points[2][2] = -fDz.getValue();
00280 points[3][0] = fDx1.getValue(); points[3][1] = -fDy1.getValue(); points[3][2] = -fDz.getValue();
00281 points[4][0] = fDx2.getValue(); points[4][1] = fDy2.getValue(); points[4][2] = fDz.getValue();
00282 points[5][0] = -fDx2.getValue(); points[5][1] = fDy2.getValue(); points[5][2] = fDz.getValue();
00283 points[6][0] = -fDx2.getValue(); points[6][1] = -fDy2.getValue(); points[6][2] = fDz.getValue();
00284 points[7][0] = fDx2.getValue(); points[7][1] = -fDy2.getValue(); points[7][2] = fDz.getValue();
00285
00286 float t1 = FATAN((fDx2.getValue()-fDx1.getValue())/(2*fDz.getValue()));
00287 float t2 = FATAN((fDy2.getValue()-fDy1.getValue())/(2*fDz.getValue()));
00288 float st1 = FSIN(t1);
00289 float st2 = FSIN(t2);
00290 float ct1 = FCOS(t1);
00291 float ct2 = FCOS(t2);
00292
00293 normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
00294 normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
00295 normals[2][0] = 0 ; normals[2][1] = ct2; normals [2][2] = -st2;
00296 normals[3][0] = -ct1; normals[3][1] = 0; normals [3][2] = -st1;
00297 normals[4][0] = 0 ; normals[4][1] = -ct2; normals [4][2] = -st2;
00298 normals[5][0] = ct1; normals[5][1] = 0; normals [5][2] = -st1;
00299
00300 for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
00301 theFaceSet->coordIndex.setValues(0,NINDICES,indices);
00302 for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
00303 theNormalBinding->value=SoNormalBinding::PER_FACE;
00304 }
00305
00306
00307 void SoTrd::generateChildren() {
00308
00309
00310
00311
00312
00313
00314 assert(children->getLength() ==0);
00315 SoSeparator *sep = new SoSeparator();
00316 SoCoordinate3 *theCoordinates = new SoCoordinate3();
00317 SoNormal *theNormals = new SoNormal();
00318 SoNormalBinding *theNormalBinding = new SoNormalBinding();
00319 SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
00320
00321
00322
00323 sep->addChild(theCoordinates);
00324 sep->addChild(theNormals);
00325 sep->addChild(theNormalBinding);
00326 sep->addChild(theFaceSet);
00327 children->append(sep);
00328 }
00329
00330
00331 void SoTrd::generateAlternateRep() {
00332
00333
00334
00335
00336 if (children->getLength() == 0) generateChildren();
00337 updateChildren();
00338 alternateRep.setValue((SoSeparator *) ( *children)[0]);
00339 }
00340
00341
00342 void SoTrd::clearAlternateRep() {
00343 alternateRep.setValue(NULL);
00344 }
00345
00346 #endif