void CCastRay::TestModelSimple(CEntity *penModel, CModelObject &mo) { // get model's bounding box for current frame FLOATaabbox3D boxModel; mo.GetCurrentFrameBBox(boxModel); boxModel.StretchByVector(mo.mo_Stretch); // get center and radius of the bounding sphere in absolute space FLOAT fSphereRadius = boxModel.Size().Length()/2.0f; FLOAT3D vSphereCenter = boxModel.Center(); vSphereCenter*=penModel->en_mRotation; vSphereCenter+=penModel->en_plPlacement.pl_PositionVector; // if the ray doesn't hit the sphere FLOAT fSphereHitDistance; if (!RayHitsSphere(cr_vOrigin, cr_vTarget, vSphereCenter, fSphereRadius+cr_fTestR, fSphereHitDistance) ) { // ignore return; } // if the ray hits the sphere closer than closest found hit point yet if (fSphereHitDistance<cr_fHitDistance && fSphereHitDistance>0.0f) { // set the current entity as new hit target cr_fHitDistance=fSphereHitDistance; cr_penHit = penModel; cr_pbscBrushSector = NULL; cr_pbpoBrushPolygon = NULL; } }
void CDlgPgCollision::DoDataExchange(CDataExchange* pDX) { CModelerView *pModelerView = CModelerView::GetActiveView(); if(pModelerView == NULL) return; CModelerDoc* pDoc = pModelerView->GetDocument(); // if transfering data from document to dialog if( !pDX->m_bSaveAndValidate) { // get collision min vector FLOAT3D vMinCollisionBox = pDoc->m_emEditModel.GetCollisionBoxMin(); // get collision max vector FLOAT3D vMaxCollisionBox = pDoc->m_emEditModel.GetCollisionBoxMax(); FLOATaabbox3D bboxCollision = FLOATaabbox3D( vMinCollisionBox, vMaxCollisionBox); m_fWidth = bboxCollision.Size()(1); m_fHeight = bboxCollision.Size()(2); m_fLenght = bboxCollision.Size()(3); m_fXCenter = bboxCollision.Center()(1); m_fYDown = vMinCollisionBox(2); m_fZCenter = bboxCollision.Center()(3); // set equality radio initial value INDEX iEqualityType = pDoc->m_emEditModel.GetCollisionBoxDimensionEquality(); // get index of curently selected collision box char achrString[ 256]; sprintf( achrString, "%d.", pDoc->m_emEditModel.GetActiveCollisionBoxIndex()); m_strCollisionBoxIndex = achrString; // get name of curently selected collision box sprintf( achrString, "%s", pDoc->m_emEditModel.GetCollisionBoxName()); m_strCollisionBoxName = achrString; // enable all controls GetDlgItem( IDC_STATIC_WIDTH)->EnableWindow( TRUE); GetDlgItem( IDC_EDIT_WIDTH)->EnableWindow( TRUE); GetDlgItem( IDC_STATIC_HEIGHT)->EnableWindow( TRUE); GetDlgItem( IDC_EDIT_HEIGHT)->EnableWindow( TRUE); GetDlgItem( IDC_STATIC_LENGHT)->EnableWindow( TRUE); GetDlgItem( IDC_EDIT_LENGHT)->EnableWindow( TRUE); m_bCollideAsBox = pDoc->m_emEditModel.edm_md.md_bCollideAsCube; // if we are colliding using sphere approximation switch( iEqualityType) { case HEIGHT_EQ_WIDTH: { m_EqualityRadio = 0; if( !m_bCollideAsBox) { GetDlgItem( IDC_STATIC_HEIGHT)->EnableWindow( FALSE); GetDlgItem( IDC_EDIT_HEIGHT)->EnableWindow( FALSE); m_fHeight = m_fWidth; } break; } case LENGTH_EQ_WIDTH: { m_EqualityRadio = 1; if( !m_bCollideAsBox) { GetDlgItem( IDC_STATIC_LENGHT)->EnableWindow( FALSE); GetDlgItem( IDC_EDIT_LENGHT)->EnableWindow( FALSE); m_fLenght = m_fWidth; } break; } case LENGTH_EQ_HEIGHT: { m_EqualityRadio = 2; if( !m_bCollideAsBox) { GetDlgItem( IDC_STATIC_LENGHT)->EnableWindow( FALSE); GetDlgItem( IDC_EDIT_LENGHT)->EnableWindow( FALSE); m_fLenght = m_fHeight; } break; } default: { ASSERTALWAYS( "None of collision dimensions are the same and that can't be."); } } // mark that the values have been updated to reflect the state of the view m_udAllValues.MarkUpdated(); } CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDlgPgCollision) DDX_SkyFloat(pDX, IDC_EDIT_WIDTH, m_fWidth); DDX_SkyFloat(pDX, IDC_EDIT_HEIGHT, m_fHeight); DDX_SkyFloat(pDX, IDC_EDIT_LENGHT, m_fLenght); DDX_SkyFloat(pDX, IDC_EDIT_XCENTER, m_fXCenter); DDX_SkyFloat(pDX, IDC_EDIT_YDOWN, m_fYDown); DDX_SkyFloat(pDX, IDC_EDIT_ZCENTER, m_fZCenter); DDX_Radio(pDX, IDC_H_EQ_W, m_EqualityRadio); DDX_Text(pDX, IDC_COLLISION_BOX_NAME, m_strCollisionBoxName); DDX_Text(pDX, IDC_COLLISION_BOX_INDEX, m_strCollisionBoxIndex); DDX_Check(pDX, IDC_COLLIDE_AS_BOX, m_bCollideAsBox); //}}AFX_DATA_MAP // if transfering data from dialog to document if( pDX->m_bSaveAndValidate) { // if we are colliding using sphere approximation if( !pDoc->m_emEditModel.edm_md.md_bCollideAsCube) { INDEX iEqualityType; switch( m_EqualityRadio) { case 0: { iEqualityType = HEIGHT_EQ_WIDTH; CString strWidth; GetDlgItem( IDC_EDIT_WIDTH)->GetWindowText(strWidth); GetDlgItem( IDC_EDIT_HEIGHT)->SetWindowText(strWidth); break; } case 1: { iEqualityType = LENGTH_EQ_WIDTH; CString strWidth; GetDlgItem( IDC_EDIT_WIDTH)->GetWindowText(strWidth); GetDlgItem( IDC_EDIT_LENGHT)->SetWindowText( strWidth ); break; } case 2: { iEqualityType = LENGTH_EQ_HEIGHT; CString strHeight; GetDlgItem( IDC_EDIT_HEIGHT)->GetWindowText(strHeight); GetDlgItem( IDC_EDIT_LENGHT)->SetWindowText( strHeight); break; } default: { ASSERTALWAYS( "Illegal value found in collision dimensions equality radio."); } } // set collision equality value if( pDoc->m_emEditModel.GetCollisionBoxDimensionEquality() != iEqualityType) { pDoc->m_emEditModel.SetCollisionBoxDimensionEquality( iEqualityType); } } // set name of curently selected collision box pDoc->m_emEditModel.SetCollisionBoxName( CTString( m_strCollisionBoxName) ); // get collision min and max vectors FLOAT3D vMinCollisionBox; FLOAT3D vMaxCollisionBox; // get sizing values vMinCollisionBox(1) = m_fXCenter-m_fWidth/2.0f; vMinCollisionBox(2) = m_fYDown; vMinCollisionBox(3) = m_fZCenter-m_fLenght/2.0f; // get origin coordinates vMaxCollisionBox(1) = m_fXCenter+m_fWidth/2.0f; vMaxCollisionBox(2) = m_fYDown+m_fHeight; vMaxCollisionBox(3) = m_fZCenter+m_fLenght/2.0f; // transfer data from dialog to document pDoc->m_emEditModel.SetCollisionBox( vMinCollisionBox, vMaxCollisionBox); pDoc->SetModifiedFlag(); // update all views pDoc->UpdateAllViews( NULL); } }