Ejemplo n.º 1
0
void RPG_Explosion::CreateAabb( hkAabb &aabb )
{
  hkVector4 centerHk, directionHk;
  vHavokConversionUtils::VisVecToPhysVecLocal(m_center, centerHk);
  vHavokConversionUtils::VisVecToPhysVecLocal(m_direction, directionHk);

  switch(m_type)
  {
  case ET_Sphere:
    {
      aabb.setFromCenterRadius(centerHk, VIS2HK_FLOAT_SCALED(m_radius));
    }
    break;

  case ET_HerringBone:
    {
      hkVector4 endPointHk;
      endPointHk.setAddMul(centerHk, directionHk, VIS2HK_FLOAT_SCALED(m_length));
      aabb.setFromLine(centerHk, endPointHk);
      aabb.expandBy(VIS2HK_FLOAT_SCALED(m_radius));
    }
    break;

  case ET_None:
  case ET_Count:
  default:
    {
      VASSERT_MSG(false, "Please specify a valid RPG_ExplosionType_e.")
    }
    break;
  }
}
Ejemplo n.º 2
0
static bool _ComputePath(const hkaiWorld* aiWorld, hkvVec3* startPoint, hkvVec3* endPoint, float radius, hkaiPathfindingUtil::FindPathInput& input, hkaiPathfindingUtil::FindPathOutput& output)
{
	VASSERT(input.m_goalPoints.getSize() == 1);

	vHavokConversionUtils::VisVecToPhysVecWorld((*startPoint), input.m_startPoint);
	vHavokConversionUtils::VisVecToPhysVecWorld((*endPoint), input.m_goalPoints[0]);
	input.m_startFaceKey = HKAI_INVALID_PACKED_KEY;
	input.m_goalFaceKeys[0] = HKAI_INVALID_PACKED_KEY;

	bool foundPath = false;
	const hkaiNavMeshQueryMediator* mediator = aiWorld ? aiWorld->getDynamicQueryMediator() : HK_NULL;
	if (mediator)
	{
		hkVector4 closestPoint;
		input.m_startFaceKey = mediator->getClosestPoint(input.m_startPoint, 3.f, closestPoint);
		if (input.m_startFaceKey != HKAI_INVALID_PACKED_KEY)
			input.m_startPoint = closestPoint;

		input.m_goalFaceKeys[0] = mediator->getClosestPoint(input.m_goalPoints[0], 3.f, closestPoint);
		if (input.m_goalFaceKeys[0] != HKAI_INVALID_PACKED_KEY)
			input.m_goalPoints[0] = closestPoint;

		if (input.m_startFaceKey != HKAI_INVALID_PACKED_KEY && input.m_goalFaceKeys[0] != HKAI_INVALID_PACKED_KEY)
		{
			input.m_agentInfo.m_diameter = VIS2HK_FLOAT_SCALED(radius*2.f);
			input.m_searchParameters.m_up.set(0,0,1);

			hkaiPathfindingUtil::findPath(*aiWorld->getStreamingCollection(), input, output);

			foundPath = (output.m_outputParameters.m_status == hkaiAstarOutputParameters::SEARCH_SUCCEEDED);
		}
	}

	return foundPath;
}
void vHavokVisualDebugger::Step()
{
  // Get the local timers to feed to the stats viewer
  // reset our VDB stats list
  if (m_physicsContext)
  {
    m_physicsContext->syncTimers(vHavokPhysicsModule::GetInstance()->GetThreadPool());
  }

  hkReal dt = Vision::GetTimer()->GetTimeDifference();

  // Step the debugger
  m_pVisualDebugger->step(dt*hkReal(1000));

  // Update camera
  hkVector4 pos; 
  vHavokConversionUtils::VisVecToPhysVecWorld(Vision::Camera.GetMainCamera()->GetPosition(),pos);
  hkVector4 dir; 
  vHavokConversionUtils::VisVecToPhysVec_noscale(Vision::Camera.GetMainCamera()->GetDirection(),dir);
  hkVector4 up;
  vHavokConversionUtils::VisVecToPhysVec_noscale(Vision::Camera.GetMainCamera()->GetObjDir_Up(), up);

  hkVector4 lookat;
  lookat.setAdd(pos,dir);

  // Havok visual debugger defaults
  float nearPlane = 0.1f;
  float farPlane = 500.f;
  float fovX = 0.f;
  float fovY = 45.f;


  VisRenderContext_cl::GetMainRenderContext()->GetClipPlanes(nearPlane, farPlane);
  VisRenderContext_cl::GetMainRenderContext()->GetFinalFOV(fovX, fovY);

  // Scale them to Havok space
  nearPlane = float(VIS2HK_FLOAT_SCALED(nearPlane));
  farPlane = float(VIS2HK_FLOAT_SCALED(farPlane));

  HK_UPDATE_CAMERA(pos, lookat, up, nearPlane, farPlane, fovY, "Vision");

  // Reset internal profiling info for next frame
  hkMonitorStream::getInstance().reset();
}
hkReal hkvSampledHeightFieldShape::getHeightAtImpl(int x, int z) const
{
#ifdef SUPPORTS_TERRAIN
  // Note we flip the sampling of (Havok Z) to be (RES - Vision Y)
  // See vHavokTerrain::CreateHkRigidBody for explanation (and other alternatives) 
  return VIS2HK_FLOAT_SCALED(m_pSector->GetHeightAt(x, m_zRes-z-1));
#else
  return 0.0f;
#endif
}
Ejemplo n.º 5
0
bool vHavokAiModule::ComputeAndDrawPath(IVRenderInterface *pRenderer, hkvVec3* startPoint, hkvVec3* endPoint, float radius, float height, float displayOffset, unsigned int color) const
{
	hkaiPathfindingUtil::FindPathInput input(1);
	hkaiPathfindingUtil::FindPathOutput output;
	bool foundPath = _ComputePath(m_aiWorld, startPoint, endPoint, radius, input, output);

	if (input.m_startFaceKey != HKAI_INVALID_PACKED_KEY && input.m_goalFaceKeys[0] != HKAI_INVALID_PACKED_KEY)
	{
		vHavokAiNavMeshDebugDisplayHandler displayHandler;
		hkReal displayOffsetHavokScale = VIS2HK_FLOAT_SCALED(displayOffset);
		hkaiNavMeshDebugUtils::_drawPathWithRadius(input, output, color, hkColor::ORANGE, &displayHandler, 0, displayOffsetHavokScale);
	}

	hkvVec3 vStartPos; vHavokConversionUtils::PhysVecToVisVecWorld(input.m_startPoint,vStartPos); 
	hkvVec3 vEndPos; vHavokConversionUtils::PhysVecToVisVecWorld(input.m_goalPoints[0],vEndPos); 
	hkvVec3 vScaledDir ( 0.f, 0.f, height );
	VSimpleRenderState_t state(VIS_TRANSP_NONE, RENDERSTATEFLAG_FRONTFACE|RENDERSTATEFLAG_WRITETOZBUFFER);	
	int sd = (input.m_startFaceKey != HKAI_INVALID_PACKED_KEY) ? 1 : 2;
	int ed = (input.m_goalFaceKeys[0] != HKAI_INVALID_PACKED_KEY) ? 1 : 2;
	pRenderer->RenderCylinder(vStartPos, vScaledDir, radius, VColorRef(255/sd, 165/sd, 0/sd), state, RENDERSHAPEFLAGS_SOLID|RENDERSHAPEFLAGS_CAP1);
	pRenderer->RenderCylinder(vEndPos, vScaledDir, radius, VColorRef(0/ed, 128/ed, 0/ed), state, RENDERSHAPEFLAGS_SOLID|RENDERSHAPEFLAGS_CAP1);

	return foundPath;
}
Ejemplo n.º 6
0
hkpShape* vHavokShapeFactory::CreateShapeFromTerrain(const VTerrainSector& terrain)
{
  // Check if shape is already cached on disk. Only try to load cached shape file outside of vForge, since otherwise the physics
  // representation will not be updated on terrain editing.
  const bool bAllowStaticMeshCaching = vHavokPhysicsModule_GetDefaultWorldRuntimeSettings().m_bEnableShapeCaching==TRUE;
  if (!Vision::Editor.IsInEditor() && bAllowStaticMeshCaching)
  {
    hkpShape *pCachedShape = vHavokCachedShape::LoadTerrainSectorShape(&terrain);
    if (pCachedShape)
      return pCachedShape;
    else
      Vision::Error.Warning("Cached HKT file for %s is missing. Please generate HKT file (see documentation for details).", terrain.GetFilename());
  }

  hkpSampledHeightFieldBaseCinfo ci; 
  ci.m_xRes = terrain.m_Config.m_iHeightSamplesPerSector[0]+1; 
  ci.m_zRes = terrain.m_Config.m_iHeightSamplesPerSector[1]+1;

  // Overlapping samples into next sectors on all edges (so res-1 is scale)
  ci.m_scale.set( VIS2HK_FLOAT_SCALED(terrain.m_Config.m_vSectorSize.x/float(ci.m_xRes-1)), 1, VIS2HK_FLOAT_SCALED(terrain.m_Config.m_vSectorSize.y/float(ci.m_zRes-1)) );
  ci.m_minHeight = VIS2HK_FLOAT_SCALED(terrain.m_fMinHeightValue);
  ci.m_maxHeight = VIS2HK_FLOAT_SCALED(terrain.m_fMaxHeightValue);

  hkvSampledHeightFieldShape* heightFieldShape = new hkvSampledHeightFieldShape(ci, &terrain);  
  const bool bExact = terrain.GetPhysicsType() >= VTerrainSector::VPHYSICSTYPE_PRECISE;
  const bool bHasHoles = terrain.HasHoles();

  if (!bExact && bHasHoles)
    Vision::Error.Warning("Terrain sector has holes but uses approximated physics representation. Therefore precise physics representation enforced.");

  // Two choices here.. could use just the heightfield as is, or
  // wrap it in a tri sampler. The tri sampler will give exact collisions, the heightfield alone will be based on collision spheres.
  // We *have* to use the accurate version in case the sector has holes
  if (bExact || bHasHoles)
  {
    hkpTriSampledHeightFieldCollection* collection;
    hkpTriSampledHeightFieldBvTreeShape* bvTree;

    if (bHasHoles) // use a slightly modified version of hkpTriSampledHeightFieldCollection in case it has holes
    {
      collection = new hkvTriSampledHeightFieldCollection(&terrain, heightFieldShape);
      bvTree = new hkvTriSampledHeightFieldBvTreeShape(collection);    
    } 
    else
    {
      collection = new hkpTriSampledHeightFieldCollection(heightFieldShape);
      bvTree = new hkpTriSampledHeightFieldBvTreeShape(collection);
    }

    // Winding must be set to WELDING_TYPE_ANTICLOCKWISE (see hkpTriSampledHeightFieldCollection::initWeldingInfo()).
    if (terrain.GetPhysicsType() == VTerrainSector::VPHYSICSTYPE_PRECISE_OFFLINE_WELDING)
      hkpMeshWeldingUtility::computeWeldingInfo(collection, bvTree, hkpWeldingUtility::WELDING_TYPE_ANTICLOCKWISE);

    collection->removeReference();
    heightFieldShape->removeReference();
    return bvTree;	
  }
  else
  {
    return heightFieldShape;
  }
}