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
00039 #ifdef G4VIS_BUILD_OI_DRIVER
00040
00041
00042 #include "HEPVis/nodes/SoTrap.h"
00043
00044 #include <assert.h>
00045 #include <cmath>
00046 #include <Inventor/SbBox.h>
00047 #include <Inventor/actions/SoGLRenderAction.h>
00048 #include <Inventor/actions/SoAction.h>
00049 #include <Inventor/fields/SoSFFloat.h>
00050 #include <Inventor/misc/SoChildList.h>
00051 #include <Inventor/nodes/SoSeparator.h>
00052 #include <Inventor/nodes/SoIndexedFaceSet.h>
00053 #include <Inventor/nodes/SoNormal.h>
00054 #include <Inventor/nodes/SoCoordinate3.h>
00055 #include <Inventor/nodes/SoNormalBinding.h>
00056 #include <Inventor/SoPrimitiveVertex.h>
00057 #include <Inventor/elements/SoTextureCoordinateElement.h>
00058
00059 #include "HEPVis/SbMath.h"
00060
00061
00062 SO_NODE_SOURCE(SoTrap)
00063
00064
00065 SoTrap::SoTrap() {
00066
00067 SO_NODE_CONSTRUCTOR(SoTrap);
00068
00069
00070 SO_NODE_ADD_FIELD(pDz, (1.0));
00071 SO_NODE_ADD_FIELD(pTheta, (0.0));
00072 SO_NODE_ADD_FIELD(pPhi, (0.0));
00073 SO_NODE_ADD_FIELD(pDy1, (1.0));
00074 SO_NODE_ADD_FIELD(pDx1, (1.0));
00075 SO_NODE_ADD_FIELD(pDx2, (1.0));
00076 SO_NODE_ADD_FIELD(pDy2, (1.0));
00077 SO_NODE_ADD_FIELD(pDx3, (1.0));
00078 SO_NODE_ADD_FIELD(pDx4, (1.0));
00079 SO_NODE_ADD_FIELD(pAlp1, (0.0));
00080 SO_NODE_ADD_FIELD(pAlp2, (0.0));
00081 SO_NODE_ADD_FIELD(alternateRep, (NULL));
00082 children = new SoChildList(this);
00083 }
00084
00085
00086 SoTrap::~SoTrap() {
00087 delete children;
00088 }
00089
00090
00091
00092 void SoTrap::initClass(){
00093
00094 SO_NODE_INIT_CLASS(SoTrap,SoShape,"Shape");
00095 }
00096
00097
00098
00099 void SoTrap::generatePrimitives(SoAction *action) {
00100
00101 SoPrimitiveVertex pv;
00102
00103
00104 SoState *state = action->getState();
00105
00106
00107
00108 SbBool useTexFunction=
00109 (SoTextureCoordinateElement::getType(state) ==
00110 SoTextureCoordinateElement::FUNCTION);
00111
00112
00113
00114
00115 const SoTextureCoordinateElement *tce = NULL;
00116 SbVec4f texCoord;
00117 if (useTexFunction) {
00118 tce = SoTextureCoordinateElement::getInstance(state);
00119 }
00120 else {
00121 texCoord[2] = 0.0;
00122 texCoord[3] = 1.0;
00123 }
00124 SbVec3f point, normal;
00125
00126
00128
00129 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
00130 point.setValue(x,y,z); \
00131 normal.setValue(nx,ny,nz); \
00132 if (useTexFunction) { \
00133 texCoord=tce->get(point,normal); \
00134 } \
00135 else { \
00136 texCoord[0]=s; \
00137 texCoord[1]=t; \
00138 } \
00139 pv.setPoint(point); \
00140 pv.setNormal(normal); \
00141 pv.setTextureCoords(texCoord); \
00142 shapeVertex(&pv);
00143
00145
00146 const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
00147 int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,
00148 4,5,6,7, SO_END_FACE_INDEX,
00149 0,1,5,4, SO_END_FACE_INDEX,
00150 1,2,6,5, SO_END_FACE_INDEX,
00151 2,3,7,6, SO_END_FACE_INDEX,
00152 3,0,4,7, SO_END_FACE_INDEX};
00153
00154
00155 float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
00156 float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
00157 float Talp1 = FTAN(pAlp1.getValue());
00158 float Talp2 = FTAN(pAlp2.getValue());
00159
00160 float points[NPOINTS][3];
00161 points[0][0] = pDx2.getValue()+pDy1.getValue()*Talp1;
00162 points[0][1] = pDy1.getValue();
00163 points[0][2] = -pDz.getValue();
00164
00165 points[1][0] = -pDx2.getValue()+pDy1.getValue()*Talp1;
00166 points[1][1] = pDy1.getValue();
00167 points[1][2] = -pDz.getValue();
00168
00169 points[2][0] = -pDx1.getValue()-pDy1.getValue()*Talp1;
00170 points[2][1] = -pDy1.getValue();
00171 points[2][2] = -pDz.getValue();
00172
00173 points[3][0] = pDx1.getValue()-pDy1.getValue()*Talp1;
00174 points[3][1] = -pDy1.getValue();
00175 points[3][2] = -pDz.getValue();
00176
00177 points[4][0] = pDx4.getValue()+pDy2.getValue()*Talp2;
00178 points[4][1] = pDy2.getValue();
00179 points[4][2] = pDz.getValue();
00180
00181 points[5][0] = -pDx4.getValue()+pDy2.getValue()*Talp2;
00182 points[5][1] = pDy2.getValue();
00183 points[5][2] = pDz.getValue();
00184
00185 points[6][0] = -pDx3.getValue()-pDy2.getValue()*Talp2;
00186 points[6][1] = -pDy2.getValue();
00187 points[6][2] = pDz.getValue();
00188
00189 points[7][0] = pDx3.getValue()-pDy2.getValue()*Talp2;
00190 points[7][1] = -pDy2.getValue();
00191 points[7][2] = pDz.getValue();
00192
00193 int i;
00194 for (i=0;i<4;i++) {
00195 points[i][0] -= pDz.getValue()*TthetaCphi;
00196 points[i][1] -= pDz.getValue()*TthetaSphi;
00197 }
00198 for (i=4;i<8;i++) {
00199 points[i][0] += pDz.getValue()*TthetaCphi;
00200 points[i][1] += pDz.getValue()*TthetaSphi;
00201 }
00202
00203 SbVec3f normals[NFACES];
00204 int nf;
00205 for (nf=0;nf<NFACES;nf++) {
00206 int j0 = indices[5*nf + 0];
00207 int j1 = indices[5*nf + 1];
00208 int j2 = indices[5*nf + 2];
00209 SbVec3f p0(points[j0][0],points[j0][1],points[j0][2]);
00210 SbVec3f p1(points[j1][0],points[j1][1],points[j1][2]);
00211 SbVec3f p2(points[j2][0],points[j2][1],points[j2][2]);
00212 normals[nf] = (p1-p0).cross(p2-p0);
00213 normals[nf].normalize();
00214 }
00215
00216 float x,y,z;
00217 int index;
00218 for (nf=0;nf<NFACES;nf++) {
00219 beginShape(action,TRIANGLE_FAN);
00220 index = indices[nf * 5];
00221 x = points[index][0];
00222 y = points[index][1];
00223 z = points[index][2];
00224 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00225 index = indices[nf * 5 + 1];
00226 x = points[index][0];
00227 y = points[index][1];
00228 z = points[index][2];
00229 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00230 index = indices[nf * 5 + 2];
00231 x = points[index][0];
00232 y = points[index][1];
00233 z = points[index][2];
00234 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00235 index = indices[nf * 5 + 3];
00236 x = points[index][0];
00237 y = points[index][1];
00238 z = points[index][2];
00239 GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
00240 endShape();
00241 }
00242 }
00243
00244
00245 SoChildList *SoTrap::getChildren() const {
00246 return children;
00247 }
00248
00249
00250
00251 void SoTrap::computeBBox(SoAction *, SbBox3f &box, SbVec3f ¢er ){
00252 float pDx= pDx1.getValue(),pDy=pDy1.getValue();
00253
00254 if (pDx2.getValue() > pDx) pDx = pDx2.getValue();
00255 if (pDx3.getValue() > pDx) pDx = pDx3.getValue();
00256 if (pDx4.getValue() > pDx) pDx = pDx4.getValue();
00257 if (pDy2.getValue() > pDy) pDy = pDy2.getValue();
00258 float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
00259 float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
00260 float Xalp = FFABS(std::tan(pAlp1.getValue())*pDy1.getValue());
00261 float Xalp2 = FFABS(std::tan(pAlp2.getValue())*pDy2.getValue());
00262 if (Xalp< Xalp2) Xalp=Xalp2;
00263 pDx += FFABS(TthetaCphi*pDz.getValue());
00264 pDx += Xalp;
00265 pDy += FFABS(TthetaSphi*pDz.getValue());
00266
00267
00268 center.setValue(0,0,0);
00269 box.setBounds(SbVec3f(-pDx,-pDy,-pDz.getValue()),
00270 SbVec3f( pDx, pDy, pDz.getValue()));
00271 }
00272
00273
00274
00275
00276
00277 void SoTrap::updateChildren() {
00278
00279
00280
00281
00282 assert(children->getLength()==1);
00283 SoSeparator *sep = (SoSeparator *) ( *children)[0];
00284 SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
00285 SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
00286 SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
00287 SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
00288
00289 const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
00290 float points[NPOINTS][3];
00291
00292 #ifdef INVENTOR2_0
00293 static long
00294 #else
00295 static int32_t
00296 #endif
00297 indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,
00298 4,5,6,7, SO_END_FACE_INDEX,
00299 0,1,5,4, SO_END_FACE_INDEX,
00300 1,2,6,5, SO_END_FACE_INDEX,
00301 2,3,7,6, SO_END_FACE_INDEX,
00302 3,0,4,7, SO_END_FACE_INDEX};
00303
00304
00305
00306 float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
00307 float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
00308 float Talp1 = FTAN(pAlp1.getValue());
00309 float Talp2 = FTAN(pAlp2.getValue());
00310
00311 points[0][0] = pDx2.getValue()+pDy1.getValue()*Talp1;
00312 points[0][1] = pDy1.getValue();
00313 points[0][2] = -pDz.getValue();
00314
00315 points[1][0] = -pDx2.getValue()+pDy1.getValue()*Talp1;
00316 points[1][1] = pDy1.getValue();
00317 points[1][2] = -pDz.getValue();
00318
00319 points[2][0] = -pDx1.getValue()-pDy1.getValue()*Talp1;
00320 points[2][1] = -pDy1.getValue();
00321 points[2][2] = -pDz.getValue();
00322
00323 points[3][0] = pDx1.getValue()-pDy1.getValue()*Talp1;
00324 points[3][1] = -pDy1.getValue();
00325 points[3][2] = -pDz.getValue();
00326
00327 points[4][0] = pDx4.getValue()+pDy2.getValue()*Talp2;
00328 points[4][1] = pDy2.getValue();
00329 points[4][2] = pDz.getValue();
00330
00331 points[5][0] = -pDx4.getValue()+pDy2.getValue()*Talp2;
00332 points[5][1] = pDy2.getValue();
00333 points[5][2] = pDz.getValue();
00334
00335 points[6][0] = -pDx3.getValue()-pDy2.getValue()*Talp2;
00336 points[6][1] = -pDy2.getValue();
00337 points[6][2] = pDz.getValue();
00338
00339 points[7][0] = pDx3.getValue()-pDy2.getValue()*Talp2;
00340 points[7][1] = -pDy2.getValue();
00341 points[7][2] = pDz.getValue();
00342
00343 int i;
00344 for (i=0;i<4;i++) {
00345 points[i][0] -= pDz.getValue()*TthetaCphi;
00346 points[i][1] -= pDz.getValue()*TthetaSphi;
00347 }
00348 for (i=4;i<8;i++) {
00349 points[i][0] += pDz.getValue()*TthetaCphi;
00350 points[i][1] += pDz.getValue()*TthetaSphi;
00351 }
00352
00353 for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
00354 theFaceSet->coordIndex.setValues(0,NINDICES,indices);
00355 theNormals->vector.deleteValues(0);
00356 theNormals->vector.insertSpace(0,6);
00357 for (int n=0;n<6;n++) {
00358 int i0 = 5*n+0,i1=5*n+1,i2=5*n+2;
00359 int j0 = theFaceSet->coordIndex[i0];
00360 int j1 = theFaceSet->coordIndex[i1];
00361 int j2 = theFaceSet->coordIndex[i2];
00362 SbVec3f p0= theCoordinates->point[j0];
00363 SbVec3f p1= theCoordinates->point[j1];
00364 SbVec3f p2= theCoordinates->point[j2];
00365 SbVec3f normal = (p1-p0).cross(p2-p0);
00366 normal.normalize();
00367 theNormals->vector.set1Value(n,normal);
00368 }
00369 theNormalBinding->value=SoNormalBinding::PER_FACE;
00370 }
00371
00372
00373 void SoTrap::generateChildren() {
00374
00375
00376
00377
00378
00379
00380 assert(children->getLength() ==0);
00381 SoSeparator *sep = new SoSeparator();
00382 SoCoordinate3 *theCoordinates = new SoCoordinate3();
00383 SoNormal *theNormals = new SoNormal();
00384 SoNormalBinding *theNormalBinding = new SoNormalBinding();
00385 SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
00386
00387
00388
00389 sep->addChild(theCoordinates);
00390 sep->addChild(theNormals);
00391 sep->addChild(theNormalBinding);
00392 sep->addChild(theFaceSet);
00393 children->append(sep);
00394 }
00395
00396
00397 void SoTrap::generateAlternateRep() {
00398
00399
00400
00401
00402 if (children->getLength() == 0) generateChildren();
00403 updateChildren();
00404 alternateRep.setValue((SoSeparator *) ( *children)[0]);
00405 }
00406
00407
00408 void SoTrap::clearAlternateRep() {
00409 alternateRep.setValue(NULL);
00410 }
00411
00412 #endif