Exemple #1
0
void RPG_Effect::UpdateCameraShake(float const deltaTime)
{
  VASSERT(m_cameraShaking);

  VisContextCamera_cl* camera = VisRenderContext_cl::GetCurrentContext()->GetCamera();
  VASSERT(camera);

  // end camera shake on timeout
  float const shakeTime = Vision::GetTimer()->GetTime() - m_cameraShakeStartTime;
  if (shakeTime >= m_cameraShakeDuration)
  {
    m_cameraShakeDuration = 0.f;
    m_cameraShakeStartTime = 0.f;
    m_cameraShakeMaxAmplitude = 0.f;
    m_cameraShaking = false;

    camera->ResetLocalTransformation();
    return;
  }

  // apply noise to the camera's position
  camera->ResetLocalTransformation();   // don't allow position updates to be cumulative
  hkvVec3 camPosition = camera->GetPosition();
  camPosition.x += GetCameraShakeNoise(camPosition.x);
  camPosition.y += GetCameraShakeNoise(camPosition.y);
  camPosition.z += GetCameraShakeNoise(camPosition.z);
  camera->SetPosition(camPosition);
}
void CRBX_ModelViewCtrl::SetFitModel()
{
	if(!m_pEntity) return;  
 
	m_fFovV = hkvMathHelpers::getFovY(m_fFovH, GetSize().x / GetSize().y);

	VisRenderContext_cl::GetMainRenderContext()->SetFOV(m_fFovH,m_fFovV);

	hkvAlignedBBox modelbox;
	m_pEntity->GetMesh()->GetVisibilityBoundingBox(modelbox);
	float fAngleH,fAngleV;
	VisRenderContext_cl::GetMainRenderContext()->GetFOV(fAngleH,fAngleV);

	float dx = hkvMath::Max(modelbox.getSizeX(),modelbox.getSizeY());
	float zx = 0.5f*dx / hkvMath::tanDeg (fAngleH*0.5f);
	float zy = 0.5f*modelbox.getSizeZ() / hkvMath::tanDeg (fAngleV*0.5f);
	
	float Dist = (hkvMath::Max(zx,zy) + dx*0.5f);

	VisContextCamera_cl* pMainCamera = Vision::Camera.GetMainCamera();
	hkvMat3 vMat;
	vMat.setFromEulerAngles(0,20,180);

	m_vCamPos.Set(Dist,0,modelbox.GetSizeZ());
	pMainCamera->Set(vMat,m_vCamPos);	
	
	if( m_pLight == NULL ) {
		m_pLight = new VisLightSource_cl( VisLightSourceType_e::VIS_LIGHT_DIRECTED , 10.0f );
	}

	m_pLight->SetPosition(pMainCamera->GetPosition());
	m_pLight->AttachToParent(pMainCamera);
	m_pLight->SetDirection(pMainCamera->GetDirection());
	m_pLight->SetIntensity(50.0f);		/// << 빛의 강도를 조절함.  나중에콜백이나 업데이트 함수에서 조절하시면됩니다.
	
	UpdateWorldAxisSystem();
}
Exemple #3
0
/// update all internal data
//////////////////////////////////////////////////////////////////////////
bool CScaler::UpdateInternalsAndGetVisibility()
{
	VisRenderContext_cl* pCtx = Vision::Contexts.GetCurrentContext();
	const VisMatrix4x4_cl& mtxProjection = pCtx->GetProjectionMatrix();
	VisContextCamera_cl* pContextCam = pCtx->GetCamera();
	pContextCam->GetWorldMatrix( m_mtxViewProjection ); // it`s View mtx and not all cells are filled?!?, fix below

	// ogl View to dx View mtx crap
	float* pGlmatrix = m_mtxViewProjection.GetFloatPtr();
	pGlmatrix[ 2 ]  = -pGlmatrix[ 2 ];
	pGlmatrix[ 6 ]  = -pGlmatrix[ 6 ];
	pGlmatrix[ 10 ] = -pGlmatrix[ 10 ];
	pGlmatrix[ 14 ] = -pGlmatrix[ 14 ];
	pGlmatrix[ 15 ] = 1.f; //this must be here, GetWorldMatrix DOES NOT fill all cells !!!

	// multiply is now DX style  (ogl is projection*view*world)
	m_mtxViewProjection *= mtxProjection;

	// get transpose mtx of ViewProjection
	m_mtxViewProjectionT = m_mtxViewProjection;
	m_mtxViewProjectionT.Transpose();

	// gen VPInverse mtx (if sended to shader, must be transposed)
	m_mtxViewProjectionInv = m_mtxViewProjection;
	m_mtxViewProjectionInv.InvertEx();

	// calculate -far & far plane vectors (homogeneous space)
	m_NearPlane.v1.SetXYZW( -1, 1, 0, 1 );
	m_NearPlane.v2.SetXYZW( 1, 1, 0, 1 );
	m_NearPlane.v3.SetXYZW( 1, -1, 0, 1 );
	m_NearPlane.v4.SetXYZW( -1, -1, 0, 1 );

	m_FarPlane.v1.SetXYZW( -1, 1, 1, 1 );
	m_FarPlane.v2.SetXYZW( 1, 1, 1, 1 );
	m_FarPlane.v3.SetXYZW( 1, -1, 1, 1 );
	m_FarPlane.v4.SetXYZW( -1, -1, 1, 1 );

	// w are all ones so Vision may be used
	m_NearPlane.v1 *= m_mtxViewProjectionInv;
	m_NearPlane.v2 *= m_mtxViewProjectionInv;
	m_NearPlane.v3 *= m_mtxViewProjectionInv;
	m_NearPlane.v4 *= m_mtxViewProjectionInv;

	m_FarPlane.v1 *= m_mtxViewProjectionInv;
	m_FarPlane.v2 *= m_mtxViewProjectionInv;
	m_FarPlane.v3 *= m_mtxViewProjectionInv;
	m_FarPlane.v4 *= m_mtxViewProjectionInv;

	_GetWorldPos( m_NearPlane, m_WorldNearPlane );
	_GetWorldPos( m_FarPlane, m_WorldFarPlane );

	GetIntersectionsAndPointsBeetween(); // will fill m_aIntesections & counter

	// skip if can`t generate proper matrix ( volume is outside of frustum )
	if( m_iInterectionsCount >= 4 ) // valid
	{
		// get clip space coords to calculate XY span
		for( int i=0; i<m_iInterectionsCount; i++ )
		{
			//m_aIntersections[ i ].w = 1.f; // Vision use w as 1 so don`t set
			m_aIntersections[ i ].z = 0.f; // TODO: should be water level
			m_aIntersections[ i ] *= m_mtxViewProjectionT; // use transposed mtx
			m_aIntersections[ i ].x /= m_aIntersections[ i ].w;
			m_aIntersections[ i ].y /= m_aIntersections[ i ].w;
			//m_aIntersections[ i ].z /= m_aIntersections[ i ].w; // we dont need Z
		}

		float fXMin = FLT_MAX; float fXMax = -FLT_MAX;
		float fYMin = FLT_MAX; float fYMax = -FLT_MAX;

		for( int i=0; i<m_iInterectionsCount; i++ )
		{
			if( m_aIntersections[ i ].x > fXMax )
				fXMax = m_aIntersections[ i ].x;
			if ( m_aIntersections[ i ].x < fXMin )
				fXMin = m_aIntersections[ i ].x;
			if( m_aIntersections[ i ].y > fYMax )
				fYMax = m_aIntersections[ i ].y;
			if ( m_aIntersections[ i ].y < fYMin )
				fYMin = m_aIntersections[ i ].y;
		}

		// build scaling matrix. it prevents h-space verts in shader to run out of range

		/* normal way
		VisMatrix4x4_cl mtxScale;
		mtxScale.Identity();
		mtxScale[ 0 ] = fXMax - fXMin;
		mtxScale[ 5 ] = fYMax - fYMin;
		mtxScale[ 12 ] = fXMin;
		mtxScale[ 13 ] = fYMin;
		mtxScale.Transpose();
		*/

		// faster way
		m_mtxScale[ 0 ] = fXMax - fXMin;
		m_mtxScale[ 5 ] = fYMax - fYMin;
		m_mtxScale[ 3 ] = fXMin;
		m_mtxScale[ 7 ] = fYMin;


		m_mtxViewProjectionInv *= m_mtxScale;

		m_NearPlane.v1.SetXYZW( 0, 1, 0, 1 );
		m_NearPlane.v2.SetXYZW( 1, 1, 0, 1 );
		m_NearPlane.v3.SetXYZW( 1, 0, 0, 1 );
		m_NearPlane.v4.SetXYZW( 0, 0, 0, 1 );

		m_FarPlane.v1.SetXYZW( 0, 1, 1, 1 );
		m_FarPlane.v2.SetXYZW( 1, 1, 1, 1 );
		m_FarPlane.v3.SetXYZW( 1, 0, 1, 1 );
		m_FarPlane.v4.SetXYZW( 0, 0, 1, 1 );

		m_NearPlane.v1 *= m_mtxViewProjectionInv;
		m_NearPlane.v2 *= m_mtxViewProjectionInv;
		m_NearPlane.v3 *= m_mtxViewProjectionInv;
		m_NearPlane.v4 *= m_mtxViewProjectionInv;

		m_FarPlane.v1 *= m_mtxViewProjectionInv;
		m_FarPlane.v2 *= m_mtxViewProjectionInv;
		m_FarPlane.v3 *= m_mtxViewProjectionInv;
		m_FarPlane.v4 *= m_mtxViewProjectionInv;
		return true;
	}else
	{
		// do not render
		return false;
	}
}
void VShadowMapGenSpotDir::Update(bool force)
{
  VisContextCamera_cl *pMainCam = m_pRendererNode->GetReferenceContext()->GetCamera();
  VASSERT(pMainCam);
  float fCamAngle = hkvMath::Abs (hkvMath::acosDeg (pMainCam->GetDirection().dot (m_vLastCameraDir)));
  hkvVec3 vCamMove = pMainCam->GetPosition() - m_vLastCameraPos;
  m_pRendererNode->GetReferenceContext()->GetViewFrustum(m_MainViewFrustum);

  float fFovX, fFovY;
  m_pRendererNode->GetReferenceContext()->GetFinalFOV(fFovX, fFovY);

  float fNear, fFar;
  m_pRendererNode->GetReferenceContext()->GetClipPlanes(fNear, fFar);

  VBaseShadowMapComponentSpotDirectional* pComponent = static_cast<VBaseShadowMapComponentSpotDirectional*>(m_pShadowComponent);

  if (m_eProjectionType == SHADOW_PROJECTION_ORTHOGRAPHIC)
  {
    bool bOverestimateCascades = pComponent->GetOverestimateCascades() ? true : false;
    if (bOverestimateCascades)
    {
      if (m_fFovX != fFovX || m_fFovY != fFovY || m_fNear != fNear)
      {
        // In case user switches the FOV at runtime we need to update it here
        float fStartDistance = fNear;
        for (int iCascade = 0; iCascade < m_iNumParts; iCascade++)
        {
          float fEndDistance = pComponent->GetCascadeRange(iCascade) + fNear;
          m_pParts[iCascade].ComputeOffset(fStartDistance, fEndDistance);
          fStartDistance = fEndDistance;
        }

        m_fFovX = fFovX;
        m_fFovY = fFovY;
        m_fNear = fNear;
        force = true;
      }

      if (force || m_vLastLightPos != m_pLightSource->GetPosition() || 
        m_vLastLightDir != m_pLightSource->GetDirection() || 
        vCamMove.getLength() > pComponent->GetShadowMapCameraUpdateInterval() || 
        fCamAngle > pComponent->GetShadowMapCameraUpdateAngle())
      {
        for (int iCascade = 0; iCascade < m_iNumParts; iCascade++)
        {
          VShadowMapPart& part = m_pParts[iCascade];
          
          VisContextCamera_cl* pCam = part.GetRenderContext()->GetCamera();
          VisContextCamera_cl *pReferenceCam = m_pRendererNode->GetReferenceContext()->GetCamera();

          hkvVec3 vCascadeCenter = pReferenceCam->GetPosition() + pReferenceCam->GetDirection() * part.m_fCenterOffset;
          pCam->SetDirection(GetDirection());

          float fRadius = part.m_fRadius + pComponent->GetShadowMapCameraUpdateInterval();

          float fCameraDistanceFromCenter = fFar;
          hkvVec3 vCamPos = vCascadeCenter - GetDirection() * fCameraDistanceFromCenter;
          pCam->SetPosition(vCamPos);

          //snapping
          hkvVec3 offset = pCam->GetWorldToCameraTransformation().getColumn(3).getAsVec3();

          float fPixelSize = (fRadius * 2) / (float)m_pShadowComponent->GetShadowMapSize();
          offset.x -= floorf(offset.x / fPixelSize) * fPixelSize;
          offset.y -= floorf(offset.y / fPixelSize) * fPixelSize;
          
          vCamPos -= pCam->GetObjDir_Right() * offset.x - pCam->GetObjDir_Up() * offset.y;
          pCam->SetPosition(vCamPos);
          
          
          // Set far clip plane so that we have z = 1 at the far side of the sphere - the shader expects this when using the BoundingBox cascade selection method.
          part.GetRenderContext()->SetClipPlanes(0.0f, fCameraDistanceFromCenter + fRadius);
          part.GetRenderContext()->SetOrthographicSize(fRadius * 2, fRadius * 2);
          part.Update();
        }

        m_vLastLightPos = m_pLightSource->GetPosition();
        m_vLastLightDir = m_pLightSource->GetDirection();
        m_vLastCameraPos = pMainCam->GetPosition();
        m_vLastCameraDir = pMainCam->GetDirection();
      }
    }
    else
    {
      float fStartDistance = 0.0f;
      for (int iCascade = 0; iCascade < m_iNumParts; iCascade++)
      {
        VShadowMapPart& part = m_pParts[iCascade];
        VisContextCamera_cl* pCam = part.GetRenderContext()->GetCamera();

        // TODO: Performance

        // Compute the extremes of the view frustum fragment for this cascade
        hkvVec3 vCorners[8];
        float fEndDistance = pComponent->GetCascadeRange(iCascade);
        part.m_fCullDistance = fEndDistance;
        part.GetViewFrustumCornersAtDistance(m_pRendererNode->GetReferenceContext(), fStartDistance, &vCorners[0]);
        part.GetViewFrustumCornersAtDistance(m_pRendererNode->GetReferenceContext(), fEndDistance,   &vCorners[4]);
        fStartDistance = fEndDistance;

        pCam->SetDirection(GetDirection());
        float fMinRight = FLT_MAX;
        float fMinUp = FLT_MAX;
        float fMaxRight = -FLT_MAX;
        float fMaxUp = -FLT_MAX;
        float fMinDist = FLT_MAX;
        float fMaxDist = -FLT_MAX;
        for (int iCorner = 0; iCorner < 8; iCorner ++ )
        {
          float fRight = pCam->GetObjDir_Right().dot (vCorners[iCorner]);
          if (fRight < fMinRight)
            fMinRight = fRight;
          if (fRight > fMaxRight)
            fMaxRight = fRight;

          float fUp = pCam->GetObjDir_Up().dot (vCorners[iCorner]);
          if (fUp < fMinUp)
            fMinUp = fUp;
          if (fUp > fMaxUp)
            fMaxUp = fUp;

          float fDist = pCam->GetDirection().dot (vCorners[iCorner]);
          if (fDist < fMinDist)
            fMinDist = fDist;
          if (fDist > fMaxDist)
            fMaxDist = fDist;
        }

        // Since we need to take geometry into account which lies in front of the view frustum, we need to
        // offset the near clip plane (in this case, the camera position) away from the view frustum
        fMinDist -= (fFar - fNear);

        hkvVec3 vCamPos = pCam->GetObjDir_Right() * ((fMinRight + fMaxRight)*0.5f) 
          + pCam->GetObjDir_Up() * ((fMinUp + fMaxUp)*0.5f)
          + pCam->GetDirection() * fMinDist;

        float fPadding = pComponent->GetShadowMapCameraUpdateInterval();
        pCam->SetPosition(vCamPos);
        part.GetRenderContext()->SetClipPlanes(0.0f, fMaxDist - fMinDist);
        part.GetRenderContext()->SetOrthographicSize(fMaxRight - fMinRight + fPadding, fMaxUp - fMinUp + fPadding);

        part.Update();
      }
    }
  }
  else if (m_eProjectionType == SHADOW_PROJECTION_PERSPECTIVE)
  {
    if (m_pLightSource->GetRadius() <= 0) //this is the case if triggered is set to false for the light
    {
      return; //do render the light at all
    }

    if (force || m_vLastLightPos != m_pLightSource->GetPosition() || m_vLastLightDir != m_pLightSource->GetDirection() ||
      m_fLastRadius != m_pLightSource->GetRadius() || m_fLastAngle != m_pLightSource->GetProjectionAngle())
    {
      VShadowMapPart& part = m_pParts[0];
      VisContextCamera_cl* pCam = part.GetRenderContext()->GetCamera();

      pCam->SetDirection(GetDirection());
      pCam->SetPosition(GetPosition());
      part.GetRenderContext()->SetClipPlanes(m_pShadowComponent->GetNearClip(), m_pLightSource->GetRadius());
      float fAngle = m_pLightSource->GetProjectionAngle();
      part.GetRenderContext()->SetFOV(fAngle, fAngle);

      part.Update();

      m_vLastLightPos = m_pLightSource->GetPosition();
      m_vLastLightDir = m_pLightSource->GetDirection();
      m_fLastRadius = m_pLightSource->GetRadius();
      m_fLastAngle = fAngle;
    }
  }

  m_iPartsRendered = 0;
}
void VFmodManager::RunTick(float fTimeDelta)
{
  VISION_PROFILE_FUNCTION(PROFILING_FMOD_OVERALL);

  if (!IsInitialized())
  {
    if (!IsOutputDevicePresent())
      InitDevice();

    return; 
  }

  // profiling scope
  {
    VISION_PROFILE_FUNCTION(PROFILING_FMOD_PUREUPDATE);

    VASSERT(m_pEventSystem!=NULL);

    // update Fmod listener attributes
    VisObject3D_cl *pListener = m_pListenerObject;
    if (pListener == NULL)
    {
      // The listener is the main camera. Check for teleportation since the last Fmod update, in
      // which case we won't use the position difference to calculate the listener speed.
      VisContextCamera_cl* pCamera = Vision::Camera.GetMainCamera();
      VisRenderContext_cl* pContext = VisRenderContext_cl::GetMainRenderContext();
      if (pCamera != NULL && pContext != NULL)
      {
        if (m_bLastListenerPositionValid && pCamera->GetLastTeleported() > m_iFrameOfLastUpdate)
          m_bLastListenerPositionValid = false;

        m_iFrameOfLastUpdate = pContext->GetLastRenderedFrame();
        pListener = pCamera;
      }
    }

    if (!pListener)
      return;

    hkvVec3 vCamPos = pListener->GetPosition();
    hkvVec3 vDir(pListener->GetObjDir()),
            vRight(pListener->GetObjDir_Right()),
            vUp(pListener->GetObjDir_Up());

    // Determine the camera velocity based on the previous known position
    hkvVec3 vCamVel(m_bLastListenerPositionValid && (fTimeDelta > 0.f) ? (vCamPos - m_vLastListenerPosition) * (1.f / fTimeDelta) : hkvVec3::ZeroVector());
    m_vLastListenerPosition = vCamPos;
    m_bLastListenerPositionValid = true;

    vUp = -vUp; // compensate for coordinate system
    m_pEventSystem->set3DListenerAttributes(0, (FMOD_VECTOR *)&vCamPos, (FMOD_VECTOR *)&vCamVel, (FMOD_VECTOR *)&vDir, (FMOD_VECTOR *)&vUp);

    // update all sound objects 
    SoundInstances().Update(fTimeDelta);

    // update all events 
    Events().Update(fTimeDelta);

    // update Fmod event system
    m_fTimeLeftOver += fTimeDelta;
    if (m_fTimeLeftOver > m_config.fTimeStep)
    { 
      m_pEventSystem->update();

#ifdef VFMOD_SUPPORTS_NETWORK
      if (m_config.bUseNetworkSystem)
        FMOD::NetEventSystem_Update();
#endif
      m_fTimeLeftOver = hkvMath::mod (m_fTimeLeftOver, m_config.fTimeStep);
    }
  }

  // do not purge sounds/ events in vForge, in order to allow toggling playback via hotspot button
  if (Vision::Editor.IsInEditor())
    return;  

  if (m_bAnyStopped)
  {
    VISION_PROFILE_FUNCTION(PROFILING_FMOD_PURGE);

    // all sounds/ events that have finished playing are removed from handling
    SoundInstances().PurgeNotPlaying();
    Events().PurgeNotPlaying();

    m_bAnyStopped = false; // reset any stopped flag
  }
}