Exemplo n.º 1
0
// setup CRenderModel class for rendering one model and eventually it's shadow(s)
void CModelObject::SetupModelRendering( CRenderModel &rm)
{
  _sfStats.IncrementCounter( CStatForm::SCI_MODELS);
  _pfModelProfile.StartTimer( CModelProfile::PTI_INITMODELRENDERING);
  _pfModelProfile.IncrementTimerAveragingCounter( CModelProfile::PTI_INITMODELRENDERING);

  // get model's data and lerp info
  rm.rm_pmdModelData = (CModelData*)GetData();
  GetFrame( rm.rm_iFrame0, rm.rm_iFrame1, rm.rm_fRatio);
  const INDEX ctVertices = rm.rm_pmdModelData->md_VerticesCt;
  if( rm.rm_pmdModelData->md_Flags & MF_COMPRESSED_16BIT) {
    // set pFrame to point to last and next frames' vertices
    rm.rm_pFrame16_0 = &rm.rm_pmdModelData->md_FrameVertices16[rm.rm_iFrame0 *ctVertices];
    rm.rm_pFrame16_1 = &rm.rm_pmdModelData->md_FrameVertices16[rm.rm_iFrame1 *ctVertices];
  } else {
    // set pFrame to point to last and next frames' vertices
    rm.rm_pFrame8_0 = &rm.rm_pmdModelData->md_FrameVertices8[rm.rm_iFrame0 *ctVertices];
    rm.rm_pFrame8_1 = &rm.rm_pmdModelData->md_FrameVertices8[rm.rm_iFrame1 *ctVertices];
  }

  // obtain current rendering preferences
  rm.rm_rtRenderType = _mrpModelRenderPrefs.GetRenderType();
  // remember blending color
  rm.rm_colBlend = MulColors( rm.rm_colBlend, mo_colBlendColor);

  // get decompression/stretch factors
  FLOAT3D &vDataStretch = rm.rm_pmdModelData->md_Stretch;
  rm.rm_vStretch(1) = vDataStretch(1) * mo_Stretch(1);
  rm.rm_vStretch(2) = vDataStretch(2) * mo_Stretch(2);
  rm.rm_vStretch(3) = vDataStretch(3) * mo_Stretch(3);
  rm.rm_vOffset     = rm.rm_pmdModelData->md_vCompressedCenter;
  // check if object is inverted (in mirror)
  BOOL bXInverted = rm.rm_vStretch(1) < 0;
  BOOL bYInverted = rm.rm_vStretch(2) < 0;
  BOOL bZInverted = rm.rm_vStretch(3) < 0;
  rm.rm_ulFlags &= ~RMF_INVERTED;
  if( bXInverted != bYInverted != bZInverted != _aprProjection->pr_bInverted) rm.rm_ulFlags |= RMF_INVERTED;

  // prepare projections
  _pfModelProfile.StartTimer( CModelProfile::PTI_INITPROJECTION);
  _pfModelProfile.IncrementTimerAveragingCounter( CModelProfile::PTI_INITPROJECTION);
  PrepareView(rm);
  _pfModelProfile.StopTimer( CModelProfile::PTI_INITPROJECTION);

  // get mip factor from projection (if needed)
  if( (INDEX&)rm.rm_fDistanceFactor==12345678) {
    FLOAT3D vObjectAbs;
    _aprProjection->PreClip( rm.rm_vObjectPosition, vObjectAbs);
    rm.rm_fDistanceFactor = _aprProjection->MipFactor( Min(vObjectAbs(3), 0.0f));
  }
  // adjust mip factor in case of dynamic stretch factor
  if( mo_Stretch != FLOAT3D(1,1,1)) {
    rm.rm_fMipFactor = rm.rm_fDistanceFactor - Log2( Max(mo_Stretch(1),Max(mo_Stretch(2),mo_Stretch(3))));
  } else {
    rm.rm_fMipFactor = rm.rm_fDistanceFactor;
  }
  // adjust mip factor by custom settings
  rm.rm_fMipFactor = rm.rm_fMipFactor*mdl_fLODMul +mdl_fLODAdd;

  // get current mip model using mip factor
  rm.rm_iMipLevel = GetMipModel( rm.rm_fMipFactor);
  mo_iLastRenderMipLevel = rm.rm_iMipLevel;
  // get current vertices mask
  rm.rm_pmmiMip = &rm.rm_pmdModelData->md_MipInfos[rm.rm_iMipLevel];

  // don't allow any shading, if shading is turned off
  if( rm.rm_rtRenderType & RT_SHADING_NONE) {
    rm.rm_colAmbient = C_WHITE|CT_OPAQUE;
    rm.rm_colLight   = C_BLACK;
  }

  // calculate light vector as seen from model, so that vertex normals
  // do not need to be transformed for lighting calculations
  FLOAT fLightDirection=(rm.rm_vLightDirection).Length();
  if( fLightDirection>0.001f) {
    rm.rm_vLightDirection /= fLightDirection;
  } else {
    rm.rm_vLightDirection = FLOAT3D(0,0,0);
  }
  rm.rm_vLightObj = rm.rm_vLightDirection * !rm.rm_mObjectRotation;

  // precalculate rendering data if needed
  extern void PrepareModelForRendering( CModelData &md);
  PrepareModelForRendering( *rm.rm_pmdModelData);

  // done with setup if viewing from this model
  if( rm.rm_ulFlags&RMF_SPECTATOR) {
    _pfModelProfile.StopTimer( CModelProfile::PTI_INITMODELRENDERING);
    return;
  }

  _pfModelProfile.StartTimer( CModelProfile::PTI_INITATTACHMENTS);
  // for each attachment on this model object
  FOREACHINLIST( CAttachmentModelObject, amo_lnInMain, mo_lhAttachments, itamo) {
    _pfModelProfile.IncrementTimerAveragingCounter( CModelProfile::PTI_INITATTACHMENTS);
    CAttachmentModelObject *pamo = itamo;
    // create new render model structure
    pamo->amo_prm = &_armRenderModels.Push();
    const BOOL bVisible = CreateAttachment( rm, *pamo);
    if( !bVisible) { // skip if not visible
      pamo->amo_prm = NULL;
      _armRenderModels.Pop();
      continue;
    } // prepare if visible
    _pfModelProfile.StopTimer( CModelProfile::PTI_INITMODELRENDERING);
    _pfModelProfile.StopTimer( CModelProfile::PTI_INITATTACHMENTS);
    pamo->amo_moModelObject.SetupModelRendering( *pamo->amo_prm);
    _pfModelProfile.StartTimer( CModelProfile::PTI_INITATTACHMENTS);
    _pfModelProfile.StartTimer( CModelProfile::PTI_INITMODELRENDERING);
  }