//called every frame. Here we set up the target paramters so that they //can be used by each node passed into the perform function. void FormationBhvr::InitAtThisTime(TimeValue t) { INode *leaderNode = GetLeader(t); if(leaderNode) { if(prevPosTime==TIME_NegInfinity||prevPosTime != t - GetTicksPerFrame()) { //get the right leaderPrevPos. leaderPrevPos = GetCurrentMatrix(leaderNode,t-GetTicksPerFrame()).GetTrans(); } leaderPos = GetCurrentMatrix(leaderNode,t).GetTrans(); leaderVel = leaderPos - leaderPrevPos;//use the preivous position to get the velocity. leaderSpeed = leaderVel.FLength(); //normalize the velocity. if(leaderSpeed!=0.0f) leaderVel /= leaderSpeed; else { leaderVel.x = leaderVel.y = leaderVel.z = 0.0f; } //set up the previous for the next time. leaderPrevPos = leaderPos; prevPosTime = t; } }
//This will set the formation void FormationBhvr::SetFormation(TimeValue t) { INode *node; Matrix3 tempMatrix; //Make sure that the leader is not part of the follower array.. RemoveLeaderFromFormation(t); INode *leader = GetLeader(t); if(leader==NULL) return; Matrix3 leaderPosition = GetCurrentMatrix(leader,t); leaderPosition.NoScale(); //kill any scale if we have it leaderPosition.Invert(); //it's inverted... int numDelegates = GetFollowerCount(t); //zero out the formation matrix that's used for saving it out. pblock->ZeroCount(follower_matrix1); pblock->ZeroCount(follower_matrix2); pblock->ZeroCount(follower_matrix3); pblock->ZeroCount(follower_matrix4); for(int i =0;i<numDelegates;i++) { node = GetFollower(t,i); if(node) { tempMatrix = GetCurrentMatrix(node,t); tempMatrix.NoScale(); Matrix3 leaderMat =tempMatrix*leaderPosition; AppendFollowerMatrix(t,leaderMat); //killed because matrix3 wasn't working ...pblock->Append(follower_matrix,1,&leaderMat); } else { //we still set up follower_matrix so that the counts //of the follower_matrix tab and the follower tab are equal. tempMatrix.IdentityMatrix(); AppendFollowerMatrix(t,tempMatrix); //pblock->Append(follower_matrix,1,&tempMat); } } }
NewtonBody* CreateRigidBody(DemoEntityManager* const scene, dFloat mass, NewtonCollision* const deformableCollision) { //create the rigid body NewtonWorld* const world = scene->GetNewton(); dMatrix matrix(GetCurrentMatrix()); //matrix.m_posit.m_y = FindFloor (world, matrix.m_posit.m_x, matrix.m_posit.m_z) + 4.0f; SetMatrix(*scene, dQuaternion(), matrix.m_posit); SetMatrix(*scene, dQuaternion(), matrix.m_posit); NewtonBody* const deformableBody = NewtonCreateDynamicBody(world, deformableCollision, &matrix[0][0]); // set the mass matrix NewtonBodySetMassProperties(deformableBody, mass, deformableCollision); // save the pointer to the graphic object with the body. NewtonBodySetUserData(deformableBody, this); // assign the wood id // NewtonBodySetMaterialGroupID (deformableBody, materialId); // set a destructor for this rigid body NewtonBodySetDestructorCallback(deformableBody, PhysicsBodyDestructor); // set the transform call back function NewtonBodySetTransformCallback(deformableBody, DemoEntity::TransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback(deformableBody, PhysicsApplyGravityForce); return deformableBody; }
//Get a bounding box. This is used for when we display the formation continously. void FormationBhvr::GetWorldBoundBox(TimeValue t, ViewExp *vpt, Box3& box) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } //make sure we have everything we need... if(DisplayFormation(t)==FALSE) return; if(GetFollowerCount(t)<=0) return; if(GetFollowerMatrixCount(t)<=0) return; //possible to not have this set when the follower is set.. INode *leaderNode; leaderNode = GetLeader(t); if(leaderNode==NULL) return; //for each follower we need to increase the bounding box by it's //world position location... for(int i =0;i<GetFollowerCount(t);i++) { if(GetFollower(t,i)) //if we have a a node... { Matrix3 worldSpace = GetFollowerMatrix(t,i)*GetCurrentMatrix(leaderNode,t); Point3 trans(worldSpace.GetTrans()); //expand the box by the worldposition... box += trans; } } }
//The display function that is used to display the formation. int FormationBhvr::Display(TimeValue t, ViewExp *vpt) { // setup int i,j; if(DisplayFormation(t)==FALSE) return FALSE; if(GetFollowerCount(t)<=0) return FALSE; if(GetFollowerMatrixCount(t)<=0) return FALSE; INode *leaderNode; leaderNode = GetLeader(t); if(leaderNode==NULL) return FALSE; //check tgo see if we have created a default sphere for drawing yet... //if we haven't then create it.. if (numpts == 0) GetSpherePoints(Point3(0.0f,0.0f,0.0f), 1.0, SpherePts); GraphicsWindow *gw = vpt->getGW(); //set the identity matrix... Matrix3 idMat; idMat.IdentityMatrix(); gw->setTransform(idMat); gw->setColor(LINE_COLOR,.815f,.976f,1.0f); float scaleRadius = GetDisplayScale(t); //set the drawing radius values based upon what the radius size is. for (i=0; i<NUMAROUND * 3; i++) ScaledPts[i] = ((SpherePts[i] * scaleRadius)); //for each follower we need to increase the bounding box by it's //world position location... for(i =0;i<GetFollowerCount(t);i++) { INode *followerNode = GetFollower(t,i); if(followerNode) //if we have a a node... { Matrix3 leaderMat = GetCurrentMatrix(leaderNode,t); leaderMat.NoScale(); Matrix3 followerMat = GetFollowerMatrix(t,i); Matrix3 worldSpace = followerMat *leaderMat; for (j=0; j<NUMAROUND * 3; j++) CurPts[j] = worldSpace*ScaledPts[j]; //adding the center to the point positions gw->polyline(NUMAROUND,&CurPts[0],NULL,NULL,TRUE,NULL); gw->polyline(NUMAROUND,&CurPts[NUMAROUND],NULL,NULL,TRUE,NULL); gw->polyline(NUMAROUND,&CurPts[NUMAROUND * 2],NULL,NULL,TRUE,NULL); } } return TRUE; }
dMatrix DemoEntity::CalculateGlobalMatrix (const DemoEntity* const root) const { dMatrix matrix (GetIdentityMatrix()); for (const DemoEntity* ptr = this; ptr != root; ptr = ptr->GetParent()) { matrix = matrix * GetCurrentMatrix (); } return matrix; }
eeVector3f cGL::UnProjectCurrent( const eeVector3f& point ) { GLfloat projMat[16]; GetCurrentMatrix( GL_PROJECTION_MATRIX, projMat ); GLfloat modelMat[16]; GetCurrentMatrix( GL_MODELVIEW_MATRIX, modelMat ); GLint viewPort[4]; GetViewport( viewPort ); eeVector3f fPoint( point ); fPoint.y = viewPort[3] - point.y; Vector3<GLfloat> tv3; UnProject( (GLfloat)fPoint.x, (GLfloat)fPoint.y, (GLfloat)fPoint.z, projMat, modelMat, viewPort, &tv3.x, &tv3.y, &tv3.z ); return eeVector3f( tv3.x, tv3.y, tv3.z ); }
HRESULT CScoringStar::RenderCageObject( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets /*= TRUE*/, BOOL bDrawAlphaSubsets /*= TRUE*/ ) { static D3DXVECTOR3 firstScoringStar(-14,-15,-150); static int spacingX = 3; D3DXMATRIX matWorld,tempMatView; // set view transform such that stars are positioned releative to camera D3DXMatrixLookAtLH( &tempMatView, m_pCageApp->GetCameraPosition(),&D3DXVECTOR3( 0, 0, 0),&D3DXVECTOR3( 0, 1, 0 ) ); pd3dDevice->SetTransform( D3DTS_VIEW, &tempMatView); if (m_bIsDark) { for (int i=m_pCageApp->GetNumCaught(); i<m_pCageApp->GetNumToWin(); i++) { m_Position = firstScoringStar; m_Position.x += (spacingX*i); GetCurrentMatrix(&matWorld); pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); CCageObject::Render(pd3dDevice); } } else { for (int i=0; i<m_pCageApp->GetNumCaught(); i++) { m_Position = firstScoringStar; m_Position.x += (spacingX*i); GetCurrentMatrix(&matWorld); pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); CCageObject::Render(pd3dDevice); } } // restore original view transform pd3dDevice->SetTransform( D3DTS_VIEW, m_pCageApp->GetViewMatrix()); return S_OK; }
void Render::Line(float x1, float y1, float x2, float y2, DWORD color) { GetCurrentMatrix().Mul(x1, y1, x1, y1); GetCurrentMatrix().Mul(x2, y2, x2, y2); if (_lineCachEnable) { LineCach cach; cach.start.x = x1; cach.start.y = y1; cach.end.x = x2; cach.end.y = y2; cach.color = color; _linesCach.push_back(cach); return; } Render::PushColorAndMul(color); DWORD currentColor = Render::GetColor(); glColor4ubv( (GLubyte*)¤tColor ); glBegin(GL_LINES); glVertex2d(x1, y1); glVertex2d(x2, y2); glEnd(); Render::PopColor(); }
void SimulationLister(DemoEntityManager* const scene, DemoEntityManager::dListNode* const mynode, dFloat timeStep) { m_delay --; if (m_delay > 0) { return; } // see if the net force on the body comes fr a high impact collision dFloat maxInternalForce = 0.0f; for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(m_myBody); joint; joint = NewtonBodyGetNextContactJoint(m_myBody, joint)) { for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) { //dVector point; //dVector normal; dVector contactForce; NewtonMaterial* const material = NewtonContactGetMaterial (contact); //NewtonMaterialGetContactPositionAndNormal (material, &point.m_x, &normal.m_x); NewtonMaterialGetContactForce(material, m_myBody, &contactForce[0]); dFloat forceMag = contactForce % contactForce; if (forceMag > maxInternalForce) { maxInternalForce = forceMag; } } } // if the force is bigger than 4 Gravities, It is considered a collision force dFloat maxForce = BREAK_FORCE_IN_GRAVITIES * m_myweight; if (maxInternalForce > (maxForce * maxForce)) { NewtonWorld* const world = NewtonBodyGetWorld(m_myBody); dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetMassMatrix(m_myBody, &mass, &Ixx, &Iyy, &Izz); dVector com; dVector veloc; dVector omega; dMatrix bodyMatrix; NewtonBodyGetVelocity(m_myBody, &veloc[0]); NewtonBodyGetOmega(m_myBody, &omega[0]); NewtonBodyGetCentreOfMass(m_myBody, &com[0]); NewtonBodyGetMatrix(m_myBody, &bodyMatrix[0][0]); com = bodyMatrix.TransformVector (com); dMatrix matrix (GetCurrentMatrix()); dQuaternion rotation (matrix); for (ShatterEffect::dListNode* node = m_effect.GetFirst(); node; node = node->GetNext()) { ShatterAtom& atom = node->GetInfo(); DemoEntity* const entity = new DemoEntity (NULL); entity->SetMesh (atom.m_mesh); entity->SetMatrix(*scene, rotation, matrix.m_posit); entity->InterpolateMatrix (*scene, 1.0f); scene->Append(entity); int materialId = 0; dFloat debriMass = mass * atom.m_massFraction; dFloat Ixx = debriMass * atom.m_momentOfInirtia.m_x; dFloat Iyy = debriMass * atom.m_momentOfInirtia.m_y; dFloat Izz = debriMass * atom.m_momentOfInirtia.m_z; //create the rigid body NewtonBody* const rigidBody = NewtonCreateBody (world, atom.m_collision, &matrix[0][0]); // set the correct center of gravity for this body NewtonBodySetCentreOfMass (rigidBody, &atom.m_centerOfMass[0]); // calculate the center of mas of the debris dVector center (matrix.TransformVector(atom.m_centerOfMass)); // calculate debris initial velocity dVector v (veloc + omega * (center - com)); // set initial velocity NewtonBodySetVelocity(rigidBody, &v[0]); NewtonBodySetOmega(rigidBody, &omega[0]); // set the debrie center of mass NewtonBodySetCentreOfMass (rigidBody, &atom.m_centerOfMass[0]); // set the mass matrix NewtonBodySetMassMatrix (rigidBody, debriMass, Ixx, Iyy, Izz); // activate // NewtonBodyCoriolisForcesMode (blockBoxBody, 1); // save the pointer to the graphic object with the body. NewtonBodySetUserData (rigidBody, entity); // assign the wood id NewtonBodySetMaterialGroupID (rigidBody, materialId); // set continue collision mode // NewtonBodySetContinuousCollisionMode (rigidBody, continueCollisionMode); // set a destructor for this rigid body NewtonBodySetDestructorCallback (rigidBody, PhysicsBodyDestructor); // set the transform call back function NewtonBodySetTransformCallback (rigidBody, DemoEntity::SetTransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback (rigidBody, PhysicsApplyGravityForce); } NewtonDestroyBody(world, m_myBody); scene->RemoveEntity (mynode); } };
int FormationBhvr::Perform(INode *node, TimeValue t, int numsubsamples, BOOL DisplayHelpers, float BhvrWeight, PerformOut &out) { Object *o = node->GetObjectRef(); if (o->ClassID() != DELEG_CLASSID) return FALSE; // this should never happen IDelegate *IDeleg = (IDelegate *) o->GetInterface(I_DELEGINTERFACE); Point3 vel= IDeleg->GetCurrentVelocity(); Point3 pos = IDeleg->GetCurrentPosition(); INode *leader = GetLeader(t); if(leader==NULL) return 0; Matrix3 formationMat; //Get the local formation matrix and check if(FindFollowerMatrix(t,node,formationMat)==FALSE) return 0; //that node doesn't exist in the formation so exit. //returned values. Point3 frc,goal; float speedwt, speedAtGoalwt; //Find the Formation Position Target in World Space. Matrix3 currentLeaderMat = GetCurrentMatrix(leader,t); currentLeaderMat.NoScale(); Matrix3 worldSpace = formationMat*currentLeaderMat; Point3 target = worldSpace.GetTrans(); //set the goal as the target goal = target; //set the force as the direction to move towards the target frc = goal - pos; float length = frc.FLength(); if(length!=0.0f) //we are not at the goal { frc /=length; //set up the leader Vector Point3 leaderVec = leaderVel*leaderSpeed; //If the target is behind you but moving towards you don't turn around to //go toward it. Instead move in the direction of the leader. if(frc%vel<0.0f && //if you are behind it length/IDeleg->GetAverageSpeed(t)<10 && //AND less than 20 frames vel%leaderVel>0.0f) //AND it is going toward you. { //set frc as leader's Velocity. frc = leaderVel; //move at half the leaderSpeed. Leader will still catch //up to you and you'll have some speed when it does. //set the speewt speedwt = (leaderSpeed*0.5f)/IDeleg->GetAverageSpeed(t); } else //we should just move towards the target. { //We need to find the speed to be it. We do this by //finding the time we will intersect our target based //upon the leader's velocity and our own velocity. vel -= leaderVec; //find time to intersect.. float newSpeed = vel.FLength(); float timeToIntersect = length/newSpeed; //from that time.. figure out what it speed should be.. newSpeed = timeToIntersect * IDeleg->GetMaxAccel(t); if(newSpeed>IDeleg->GetAverageSpeed(t)) newSpeed = IDeleg->GetAverageSpeed(t); //check to see if we will move past the goal.. if so //move the goal along the leader vec. This reduces overshooting //the goal and decreases wobbling. if((newSpeed+leaderSpeed)>length) { goal += leaderVel*(leaderSpeed); frc = goal -pos; float newLength = frc.FLength(); if(newLength!=0.0f) //check for if zero to avoid divide by zero.. { frc /= newLength; speedwt = (newSpeed+leaderSpeed)/IDeleg->GetAverageSpeed(t); } else { speedwt = 0.0f; } } else //far enough away.. leave the ole frc value.. speedwt = (newSpeed+leaderSpeed)/IDeleg->GetAverageSpeed(t); } } else //we are at the goal { frc.x = frc.y = frc.z = 0.0f; //set the speedwt to be the leaderSpeed speedwt = leaderSpeed/IDeleg->GetAverageSpeed(t); } frc *= BhvrWeight *IDeleg->GetAverageSpeed(t); //scale by weight and average speed.. //set the speedWtAtGoal.. We want it to be the speed of the leader speedAtGoalwt = leaderSpeed/IDeleg->GetAverageSpeed(t); //Display Any Helpers. if (DisplayHelpers && IDeleg->OkToDisplayMyForces()) { if (DisplayTarget(t)) IDeleg->SphereDisplay(goal,pblock->GetFloat(target_scale),GetTargetColor(t)); if (DisplayForce(t)) IDeleg->LineDisplay(IDeleg->GetCurrentPosition(),IDeleg->GetCurrentPosition()+frc,GetForceColor(t),TRUE); } //set up the out structure.. out.frc = frc; out.goal = goal; out.speedwt = speedwt; out.speedAtGoalwt = speedAtGoalwt; return BHVR_SETS_FORCE | BHVR_SETS_GOAL | BHVR_SETS_SPEED; }
void SimulationPostListener(DemoEntityManager* const scene, DemoEntityManager::dListNode* const mynode, dFloat timeStep) { // see if the net force on the body comes fr a high impact collision dFloat breakImpact = 0.0f; for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(m_myBody); joint; joint = NewtonBodyGetNextContactJoint(m_myBody, joint)) { for (void* contact = NewtonContactJointGetFirstContact(joint); contact; contact = NewtonContactJointGetNextContact(joint, contact)) { dVector contactForce; NewtonMaterial* const material = NewtonContactGetMaterial(contact); dFloat impulseImpact = NewtonMaterialGetContactMaxNormalImpact(material); if (impulseImpact > breakImpact) { breakImpact = impulseImpact; } } } // if the force is bigger than N time Gravities, It is considered a collision force breakImpact *= m_myMassInverse; // breakImpact = 1000.0f; if (breakImpact > BREAK_IMPACT_IN_METERS_PER_SECONDS) { NewtonWorld* const world = NewtonBodyGetWorld(m_myBody); dMatrix bodyMatrix; dVector com(0.0f); dVector veloc(0.0f); dVector omega(0.0f); dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetVelocity(m_myBody, &veloc[0]); NewtonBodyGetOmega(m_myBody, &omega[0]); NewtonBodyGetCentreOfMass(m_myBody, &com[0]); NewtonBodyGetMatrix(m_myBody, &bodyMatrix[0][0]); NewtonBodyGetMass(m_myBody, &mass, &Ixx, &Iyy, &Izz); com = bodyMatrix.TransformVector(com); dMatrix matrix(GetCurrentMatrix()); dQuaternion rotation(matrix); // we need to lock the world before creation a bunch of bodies scene->Lock(m_lock); for (FractureEffect::dListNode* node = m_effect.GetFirst(); node; node = node->GetNext()) { FractureAtom& atom = node->GetInfo(); DemoEntity* const entity = new DemoEntity(dMatrix(rotation, matrix.m_posit), NULL); entity->SetMesh(atom.m_mesh, dGetIdentityMatrix()); scene->Append(entity); int materialId = 0; dFloat debriMass = mass * atom.m_massFraction; //create the rigid body NewtonBody* const rigidBody = NewtonCreateDynamicBody(world, atom.m_collision, &matrix[0][0]); // calculate debris initial velocity dVector center(matrix.TransformVector(atom.m_centerOfMass)); dVector v(veloc + omega.CrossProduct(center - com)); // set initial velocity NewtonBodySetVelocity(rigidBody, &v[0]); NewtonBodySetOmega(rigidBody, &omega[0]); // set the debris mass properties, mass, center of mass, and inertia NewtonBodySetMassProperties(rigidBody, debriMass, atom.m_collision); // save the pointer to the graphic object with the body. NewtonBodySetUserData(rigidBody, entity); // assign the wood id NewtonBodySetMaterialGroupID(rigidBody, materialId); // set continuous collision mode // NewtonBodySetContinuousCollisionMode (rigidBody, continueCollisionMode); // set a destructor for this rigid body NewtonBodySetDestructorCallback(rigidBody, PhysicsBodyDestructor); // set the transform call back function NewtonBodySetTransformCallback(rigidBody, DemoEntity::TransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback(rigidBody, PhysicsApplyGravityForce); } NewtonDestroyBody(m_myBody); scene->RemoveEntity(mynode); // unlock the work after done with the effect scene->Unlock(m_lock); } }
KVDetector* KVGeoImport::GetCurrentDetector() { // Returns pointer to KVDetector corresponding to current location // in geometry. Detector is created and added to array if needed. // We also set up any geometry structure elements (from nodes beginning with "STRUCT_") KVString detector_name; Bool_t multilay; TGeoVolume* detector_volume = GetCurrentDetectorNameAndVolume(detector_name,multilay); // failed to identify current volume as part of a detector if(!detector_volume) return 0; // has detector already been built ? if not, do it now KVDetector* det = fArray->GetDetector(detector_name); if(!fCreateArray){ if(det){ // set matrix & shape for entrance window if not done yet if(!det->GetEntranceWindowMatrix()){ det->SetEntranceWindowMatrix(GetCurrentMatrix()); det->SetEntranceWindowShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // set matrix & shape for active layer det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } } } else { if(!det) { det = BuildDetector(detector_name, detector_volume); if(det) { // Setting the entrance window shape and matrix // ============================================ // for consistency, the matrix and shape MUST correspond // i.e. we cannot have the matrix corresponding to the entrance window // of a multilayer detector and the shape corresponding to the // whole detector (all layers) - otherwise, calculation of points // on detector entrance window will be false! // Info("GetCurrentDetector","Setting EW matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetEntranceWindowMatrix(GetCurrentMatrix()); det->SetEntranceWindowShape((TGeoBBox*)GetCurrentVolume()->GetShape()); TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // first layer of detector (or only layer) is also active layer // Info("GetCurrentDetector","and also setting active layer matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } fArray->Add(det); Int_t nstruc = CurrentStructures().GetEntries(); if(nstruc){ // Build and add geometry structure elements KVGeoStrucElement* ELEM = fArray; for(register int i=0;i<nstruc;i++){ KVGeoStrucElement* elem = (KVGeoStrucElement*)CurrentStructures()[i]; KVGeoStrucElement* nextELEM = ELEM->GetStructure(elem->GetName()); if(!nextELEM){ // make new structure nextELEM = new KVGeoStrucElement(elem->GetName(), elem->GetType()); nextELEM->SetNumber(elem->GetNumber()); ELEM->Add(nextELEM); } ELEM=nextELEM; } // add detector to last structure ELEM->Add(det); } } } else { // Detector already built, are we now in its active layer ? TString vol_name(GetCurrentVolume()->GetName()); if(!multilay || vol_name.BeginsWith("ACTIVE_")){ // Info("GetCurrentDetector","Setting active layer matrix to current matrix:"); // GetCurrentMatrix()->Print(); det->SetActiveLayerMatrix(GetCurrentMatrix()); det->SetActiveLayerShape((TGeoBBox*)GetCurrentVolume()->GetShape()); } } } return det; }