/// \brief
  ///    Helper function to retrieve current distance to a given plane
  ///
  /// \param vCameraPos
  ///   Camera position to test the distance against
  /// \param fLODScaleSqr
  ///   Square of the LOD scaling factor
  /// \param fPlane
  ///   Reference plane distance, will be subtracted from final result
  ///
  /// \returns
  ///   Relative distance from object to given plane
  inline float GetDistanceToPlane(const hkvVec3& vCameraPos, float fLODScaleSqr=1.f, float fPlane=0.f) const
  {
    int iLODMode = m_iPerformTestFlags&VIS_PERFORM_LODTEST;
    float fDistSqr;
    switch (iLODMode)
    {
    case VIS_LOD_TEST_NONE:
      fDistSqr = 0.0f;
      break;
    case VIS_LOD_TEST_CLIPPOSITION:
      fDistSqr = vCameraPos.getDistanceToSquared(m_vClipReference);
      break;
    case VIS_LOD_TEST_CLIPPOSITION|VIS_LOD_TEST_APPLYLODSCALING:
      fDistSqr = vCameraPos.getDistanceToSquared(m_vClipReference)*fLODScaleSqr;
      break;
    case VIS_LOD_TEST_BOUNDINGBOX:
      fDistSqr = m_BoundingBox.getDistanceToSquared(vCameraPos);
      break;
    case VIS_LOD_TEST_BOUNDINGBOX|VIS_LOD_TEST_APPLYLODSCALING:
      fDistSqr = m_BoundingBox.getDistanceToSquared(vCameraPos)*fLODScaleSqr;
      break;
    default:
      VASSERT_MSG(false,"Invalid combination of LOD flags");
      return false;
    }

    return hkvMath::sqrt(fDistSqr) - fPlane;
  }
示例#2
0
	VOVERRIDE void OnClick(VMenuEventDataObject *pEvent) 
	{
		VDialog::OnClick(pEvent);

 		hkvVec2 vMousePos = GetContext()->GetCurrentMousePos();
 		hkvVec3 vDir;
 		Vision::Contexts.GetCurrentContext()->GetTraceDirFromScreenPos(vMousePos.x, vMousePos.y, vDir, 10000.f);
 		hkvVec3 vFrom = Vision::Camera.GetCurrentCameraPosition();
 		hkvVec3 vTo = vFrom + vDir;

		const float v2h = vHavokConversionUtils::GetVision2HavokScale();
		hkVector4 from; from.set( vFrom.x*v2h, vFrom.y*v2h, vFrom.z*v2h );
		hkVector4 to; to.set( vTo.x*v2h, vTo.y*v2h, vTo.z*v2h );

		hkaiNavMeshQueryMediator::HitDetails hit;
		hit.m_hitFaceKey = HKAI_INVALID_PACKED_KEY;
		hit.m_hitFraction = -1.f;
		if (vHavokAiModule::GetInstance()->GetAiWorld()->getDynamicQueryMediator()->castRay(from, to, hit))
		{
			hkVector4 hitPoint; hitPoint.setInterpolate(from, to, hit.m_hitFraction);
			hitPoint.mul4( vHavokConversionUtils::GetHavok2VisionScale() );
			if (pEvent->m_iButtons & BUTTON_LMOUSE)
			{
				vStartPoint.set( hitPoint(0), hitPoint(1), hitPoint(2) );				
			}
			else
			{
				vEndPoint.set( hitPoint(0), hitPoint(1), hitPoint(2) );
			}
		}
	}
 /// \brief
 ///    Helper function for visibility loop implementations
 ///
 /// \param vCameraPos
 ///   Camera position to test LOD clipping
 /// \param fLODScaleSqr
 ///   Square of the LOD scaling factor
 ///
 /// \returns
 ///   true if the object is clipped either by near of far clip distance (if specified)
 inline bool IsNearOrFarClipped(const hkvVec3& vCameraPos, float fLODScaleSqr=1.f) const
 {
   // changes in this function have to be reflected in SPU version IsNearOrFarClipped
   int iLODMode = m_iPerformTestFlags&VIS_PERFORM_LODTEST;
   float fDistSqr;
   switch (iLODMode)
   {
   case VIS_LOD_TEST_NONE:
     return false;
   case VIS_LOD_TEST_CLIPPOSITION:
     fDistSqr = vCameraPos.getDistanceToSquared(m_vClipReference);
     break;
   case VIS_LOD_TEST_CLIPPOSITION|VIS_LOD_TEST_APPLYLODSCALING:
     fDistSqr = vCameraPos.getDistanceToSquared(m_vClipReference)*fLODScaleSqr;
     break;
   case VIS_LOD_TEST_BOUNDINGBOX:
     fDistSqr = m_BoundingBox.getDistanceToSquared(vCameraPos);
     break;
   case VIS_LOD_TEST_BOUNDINGBOX|VIS_LOD_TEST_APPLYLODSCALING:
     fDistSqr = m_BoundingBox.getDistanceToSquared(vCameraPos)*fLODScaleSqr;
     break;
   default:
     VASSERT_MSG(false,"Invalid combination of LOD flags");
     return false;
   }
   return ((m_fNearClipDistance>0.f) && (fDistSqr<(m_fNearClipDistance*m_fNearClipDistance))) 
       || ((m_fFarClipDistance>0.f) && (fDistSqr>=(m_fFarClipDistance*m_fFarClipDistance)));
 }
  bool LineConeIntersection(IVRenderInterface *pRenderer, const hkvVec3 &vConePos, const hkvVec3 &vConeAxis, float fConeAngle, 
                            const hkvVec3 &vLineStart, const hkvVec3 &vLineDir, hkvVec3 &vIntersection)
  {  
    // cull back cone
    float fConeLineAngle = vConeAxis.dot(vLineDir);
    if (fConeLineAngle < 0)
      return false;

    float fCosAngle = hkvMath::cosDeg(fConeAngle);
    float fCosSquared = fCosAngle*fCosAngle;
    hkvVec3 vLineToCone = vLineStart - vConePos;
    float fDotA = vConeAxis.dot(vLineToCone);
    float fDotB = vLineDir.dot(vLineToCone);
    float fDotC = vLineToCone.dot(vLineToCone);

    float a = fConeLineAngle*fConeLineAngle - fCosSquared;
    float b = fConeLineAngle*fDotA - fCosSquared*fDotB;
    float c = fDotA*fDotA - fCosSquared*fDotC;

    float fInnerValue = b*b-4*a*c;
    float fDenominator = 2*a;
    if(fInnerValue < 0.0f || fDenominator == 0.0f)
      return false;

    float fSqrtInnerValue = sqrt(fInnerValue);
    float t1 = (-b + fSqrtInnerValue)/fDenominator;
    float t2 = (-b - fSqrtInnerValue)/fDenominator;

    // choose front cone 
    float t = (t1 > t2) ? t1 : t2;

    vIntersection = vLineStart+vLineDir*t;

    return true;
  }
bool RPG_PlayerCharacterSynchronizationGroup::QuerySynchronize(const VNetworkViewContext& context, VNetworkSynchronizationGroupInstanceInfo_t &instanceInfo, VMessageSettings& out_paketSettings)
{
  RPG_PlayerCharacter *pObj = (RPG_PlayerCharacter*) instanceInfo.m_pInstance;
  VHistoryData* pData = (VHistoryData*) instanceInfo.m_pCustomData;

  // Save previously changed data, will be compared against the current changes.
  BYTE iPreviousChangedDataFlags = pData->m_iChangedDataFlags;
  // Add data flags, will be removed if following extrapolation tests succeed.
  pData->m_iChangedDataFlags |= VCD_DataFlags;

  hkvVec3 vInterpolatedEntry(false);
  float fEpsilon = 0.5f * Vision::World.GetGlobalUnitScaling();
  // Extrapolate current position
  pData->m_positionHistory.Interpolate (&vInterpolatedEntry, context.m_iCurrentServerTimeMS);
  const hkvVec3 vCurrentPos = pObj->GetPosition(); 
  if (vCurrentPos.Equals(vInterpolatedEntry, fEpsilon))
    pData->m_iChangedDataFlags &= ~VCD_POSITION; // Remove position flag

  // Extrapolate current rotation
  pData->m_rotationHistory.Interpolate (&vInterpolatedEntry, context.m_iCurrentServerTimeMS);
  const hkvVec3 vCurrentOrientation = pObj->GetOrientation();
  if (vCurrentOrientation.Equals(vInterpolatedEntry, fEpsilon))
    pData->m_iChangedDataFlags &= ~VCD_ROTATION; // Remove rotation flag


  // Change from previous tick, send changes reliably
  if ((iPreviousChangedDataFlags^pData->m_iChangedDataFlags) != 0)
  {
    pData->m_iDataFlagsToSend = (iPreviousChangedDataFlags^pData->m_iChangedDataFlags) | pData->m_iChangedDataFlags;
    out_paketSettings.SetReliability (VMR_Reliable_Ordered);
    out_paketSettings.SetPriority (VMP_HighPriority);
    out_paketSettings.SetOrderingChannel (1);
    return true;
  }
  // No change from previous tick
  else
  {
    // Is there anything to send?
    if ((pData->m_iChangedDataFlags & VCD_DataFlags) != 0)
    {
      // Continuous changes are sent unreliably
      pData->m_iDataFlagsToSend = pData->m_iChangedDataFlags;
      out_paketSettings.SetReliability (VMR_Unreliable_Sequenced);
      out_paketSettings.SetPriority (VMP_MediumPriority);
      out_paketSettings.SetOrderingChannel (1);
      return true;
    }
    else
    {
      return false;
    }
  }
}
void VFpsCameraEntity::GetCurrentMoveAxes(hkvVec3& vForward, hkvVec3& vRight, hkvVec3& vUp) const
{
  VFreeCamera::GetCurrentMoveAxes(vForward, vRight, vUp);

  // Disable vertical movement.
  vUp = hkvVec3::ZeroVector();

  // Constrain horizontal movement to the XY-plane.
  vForward.z = vRight.z = 0.0f;
  vForward.normalize();
  vRight.normalize();
}
示例#7
0
hkvVec3 RPG_Explosion::GetHerringBoneImpulse( hkvVec3 const& position )
{
  hkvVec3 impulse(0.0f, 0.0f, 0.0f);

  hkvVec3 attackLine = m_direction;
  attackLine.z = 0.0f;
  attackLine.normalize();
  float const lineProjection = hkvMath::Max(0.0f, position.dot(attackLine) - m_center.dot(attackLine));
  hkvVec3 const& closestPointOnAttackLine = m_center + lineProjection * attackLine;
  impulse = (position - closestPointOnAttackLine);
  impulse.z = 0.0f;
  float distanceLineToImpact = impulse.getLengthAndNormalize();
  if(hkvMath::isFloatEqual(0.0f, distanceLineToImpact))
  {
    if(Vision::Game.GetFloatRand() > 0.5)
    {
      impulse.x = attackLine.y;
      impulse.y = -attackLine.x;
    }
    else
    {
      impulse.x = -attackLine.y;
      impulse.y = -attackLine.x;
    }
  }
  impulse += attackLine;
  impulse.normalize();
  
  float const strengthScale = hkvMath::Max(0.0f, (m_length - lineProjection) / m_length) *
    hkvMath::Max(0.0f, (m_radius - distanceLineToImpact) / m_radius);

  impulse.z = 0.1f;
  return impulse * strengthScale * m_impulseStrength;
}
// Idling
void RPG_PlayerControllerState::Idling::OnTick(RPG_ControllerComponent *const controller, float const deltaTime)
{
  RPG_ControllerStateBase::OnTick(controller, deltaTime);

  RPG_PlayerControllerComponent *playerController = vstatic_cast<RPG_PlayerControllerComponent*>(controller);

  RPG_PlayerControllerInput const& input = playerController->GetInput();
  RPG_PlayerControllerInput const& prevInput = playerController->GetPrevInput();

  // Tick special attacks
  if(RPG_PlayerControllerState::OnTickSpecialAttacks(playerController, input, prevInput))
  {
    return;
  }

  // Move
  bool const primaryDown = input.IsDown(RPG_PlayerControllerInput::B_PRIMARY, prevInput);
  bool const primaryHeld = input.IsPressed(RPG_PlayerControllerInput::B_PRIMARY) && prevInput.IsPressed(RPG_PlayerControllerInput::B_PRIMARY);

  if(primaryDown || primaryHeld)
  {
    if(primaryDown && input.m_targetEntity)
    {
      // Move to target
      controller->SetTarget(input.m_targetEntity);
      controller->SetTargetPoint(input.m_targetEntity->GetPosition());
    }
    else
    {
      // Move to point
      controller->SetTarget(NULL);
      controller->SetTargetPoint(input.m_targetPoint);
    }

    hkvVec3 const targetPoint = controller->GetTargetPoint();
    hkvVec3 const targetPointToCharacter(controller->GetCharacter()->GetPosition() - targetPoint);
    float const targetPointToCharactedDistSqr = targetPointToCharacter.getLengthSquared();
    float const distTolerance = hkvMath::Max(60.0f, controller->GetPathGoalReachedTolerance());
    float const distToleranceSqr = distTolerance * distTolerance;

    if(targetPointToCharactedDistSqr > distToleranceSqr)
    {
      controller->SetState(RPG_ControllerStateId::kMoving);
      return;
    }
  }
}
示例#9
0
void VFreeCamera::GetCurrentMoveAxes(hkvVec3& vForward, hkvVec3& vRight, hkvVec3& vUp) const
{
  vUp.set(0.0f, 0.0f, 1.0f);

  hkvMat3 mat(hkvNoInitialization);
  GetRotationMatrix(mat);
  vForward = mat.getAxis(0);
  vRight = mat.getAxis(1);
}
示例#10
0
bool VWallmarkManager::IsTracePointOnPlane(const hkvVec3& vPos, const hkvVec3& vNormal, float fTraceRad, float fEpsilon, hkvVec3& vNewNormal)
{
  hkvVec3 vStart = vPos + vNormal*fTraceRad;
  hkvVec3 vEnd = vPos - vNormal*fTraceRad;

#ifdef WALLMARKS_USE_VISION_TRACELINES
  VisTraceLineInfo_t result;
  if (Vision::CollisionToolkit.TraceLine(vStart,vEnd,(ULONG)VIS_TRACE_ALL,(ULONG)VIS_TRACE_NONE,NULL,NULL,&result))
    return false; // no hit

  // only allow wallmarks on static geometry and terrain
  if (result.hitType != VIS_TRACETYPE_STATICGEOMETRY  &&  result.hitType != VIS_TRACETYPE_TERRAIN)
    return false;

  if (hkvMath::Abs (result.distance - fTraceRad)>fEpsilon)
    return false;

  // too much deviation from plane normal
  vNewNormal = result.primitivePlane.m_vNormal;

  float fDot = vNewNormal.dot(vNormal);
  if (hkvMath::Abs (fDot-1.f)>fEpsilon)
    return false;
#else
  IVisPhysicsModule_cl *pPhysMod = Vision::GetApplication()->GetPhysicsModule();
  VisPhysicsHit_t result;
  if (pPhysMod==NULL || !pPhysMod->Raycast(vStart,vEnd,result))
    return false;

  // only allow wallmarks on static geometry and terrain
  if (result.eHitType != VIS_TRACETYPE_STATICGEOMETRY  &&  result.eHitType != VIS_TRACETYPE_TERRAIN)
    return false;

  if (hkvMath::Abs ((result.fHitFraction - 0.5f)*fTraceRad)>fEpsilon)
    return false;

  //NOTE: result.vImpactNormal is the interpolated vertex normal and thus not useful here
  vNewNormal = vNormal;
#endif

//  Vision::Game.DrawSingleLine(vPos,vPos+vNewNormal*20.f);

  return true;
}
示例#11
0
void RPG_Projectile::Fire(hkvVec3 position, hkvVec3 direction, float speed)
{
  VASSERT(m_characterOwner);
  m_spawnTime = Vision::GetTimer()->GetTime();

  m_currentPosition = position;
  SetPosition(position);

  VASSERT_MSG(direction.isNormalized(), "Please normalize your projectile fire direction.");
  m_direction = direction;
  m_speed = speed;

  hkvMat3 vRotation;
  vRotation.setLookInDirectionMatrix(m_direction);
  SetRotationMatrix(vRotation);

  CreateShapePhantom();

  // create inflight effect
  CreateEffect(PFX_Inflight);
}
示例#12
0
  /// \brief
  ///   Initializes useful default
  inline void InitDefaults()
  {
    m_bSortTextureChannels = false;
    m_bUseTempFolder = false;
    m_sTerrainFolder = "TerrainScene";
    m_iSectorCount[0] = m_iSectorCount[1] = 16;
    m_fViewDistance = 100000.f;
    m_iHeightSamplesPerSector[0] = m_iHeightSamplesPerSector[1] = 128; ///< ideal size
    m_vSectorSize.set(10000.f,10000.f);
    m_iTilesPerSector[0] = m_iTilesPerSector[1] = 16;
    m_iDensityMapSamplesPerSector[0] = m_iDensityMapSamplesPerSector[1] = 32;
    m_vTerrainPos.set(0.f,0.f,0.f);
    m_fPurgeInterval = 100.f;
    m_iMemoryLimit = 500;
    m_iDefaultWeightmapResolution[0] = m_iDefaultWeightmapResolution[1] = 512;
    m_iMaterialMapResolution[0] = m_iMaterialMapResolution[1] = 0; // no material map by default

    m_fVisibilityHeightOverTerrain = 2000.f;
    m_iReplacementLOD = -1;
    m_fReplacementDistance = -1.f;
    m_bDistanceBasedLODOnly = false;
    m_bIgnoreHeightForLOD = false;
    m_bNormalmapUsesBorder = false;
    m_bSceneSpecificLightmaps = false;
    m_bUseThreeWayMapping = false;
    m_bUseNormalMapping = false;
    m_bUseLightMapping = false;
    m_fPrecacheMargin = 1.0f;

	m_iOldSectorCount[0] = 0;	
	m_iOldSectorCount[1] = 0;	

	m_iOldSectorStartIndex[0] = 0;	// For Terrain sector expansion
	m_iOldSectorStartIndex[1] = 0;

	m_iNewSectorStartIndex[0] = 0;	// For Terrain sector expansion
	m_iNewSectorStartIndex[1] = 0;

    Finalize();
  }
// Moving
void RPG_PlayerControllerState::Moving::OnTick(RPG_ControllerComponent *const controller, float const deltaTime)
{
  RPG_ControllerStateBase::OnTick(controller, deltaTime);

  RPG_PlayerControllerComponent *playerController = vstatic_cast<RPG_PlayerControllerComponent*>(controller);

  RPG_PlayerControllerInput const& input = playerController->GetInput();
  RPG_PlayerControllerInput const& prevInput = playerController->GetPrevInput();

  // Tick special attacks
  if(RPG_PlayerControllerState::OnTickSpecialAttacks(playerController, input, prevInput))
  {
    return;
  }

  // Move or melee
  bool const primaryDown = input.IsDown(RPG_PlayerControllerInput::B_PRIMARY, prevInput);
  bool const primaryHeld = input.IsPressed(RPG_PlayerControllerInput::B_PRIMARY) && prevInput.IsPressed(RPG_PlayerControllerInput::B_PRIMARY);

  // Update target on click
  if(primaryDown)
  {
    playerController->SetTarget(input.m_targetEntity);
  }

  RPG_Character *const character = playerController->GetCharacter();
  RPG_DamageableEntity *const target = playerController->GetTarget();

  if(target)
  {
    hkvVec3 targetToCharacterProjectedDir;
    float targetToCharacterProjectedDist;
    RPG_ControllerUtil::GetProjectedDirAndDistanceFromTarget(character, target, targetToCharacterProjectedDir, targetToCharacterProjectedDist);

    float const minDist = RPG_ControllerUtil::GetMinimumDistanceToAttack(character, target);

    if(targetToCharacterProjectedDist > minDist)
    {
      controller->SetTargetPoint(target->GetPosition() + (target->GetCollisionRadius() + character->GetCollisionRadius()) * targetToCharacterProjectedDir);
    }
    else
    {
      controller->GetCharacter()->RaiseAnimationEvent(RPG_CharacterAnimationEvent::kMeleeAttack);
      controller->SetState(RPG_ControllerStateId::kMeleeAttacking);
      return;
    }
  }
  else if(primaryDown || primaryHeld)
  {
    controller->SetTargetPoint(input.m_targetPoint);
  }

  // Handle target reached or target update
  hkvVec3 const targetPoint = controller->GetTargetPoint();
  hkvVec3 const targetPointToCharacter(character->GetPosition() - targetPoint);
  float const targetPointToCharactedDistSqr = targetPointToCharacter.getLengthSquared();
  float const pathGoaltoleranceSqr = controller->GetPathGoalReachedTolerance() * controller->GetPathGoalReachedTolerance();

  if(targetPointToCharactedDistSqr <= pathGoaltoleranceSqr)
  {
    controller->SetState(RPG_ControllerStateId::kIdling);
    return;
  }
  else if(primaryDown || primaryHeld)
  {
    controller->RequestPath(targetPoint);
  }

  // Reorient
  hkvVec3 dir;
  RPG_ControllerUtil::CalcDirection(dir, controller->GetCharacter()->GetDirection(), controller->GetDirection(), 0.25f);
  controller->GetCharacter()->SetDirection(dir);
}
示例#14
0
void vHavokShapeFactory::ExtractScaling(const hkvMat4 &mat, hkvVec3& destScaling)
{
  hkvVec3 vx(hkvNoInitialization),vy(hkvNoInitialization),vz(hkvNoInitialization);
  mat.getAxisXYZ (&vx, &vy, &vz);
  destScaling.set(vx.getLength(),vy.getLength(),vz.getLength());
}