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;
  }
}
示例#2
0
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);
  }
}