///
  /// \brief
  ///   Get a Havok Physics world space vector from a Vision render space vector; taking Vision scaling into account.
  ///
  VHAVOK_IMPEXP static HK_FORCE_INLINE void VisVecToPhysVecWorld(const hkvVec4& visV, hkVector4& physV)
  {
	  physV.load<4, HK_IO_NATIVE_ALIGNED>(&visV.data[0]);
	  physV.mul(m_cachedVis2PhysScale);
	  physV.add(*m_cachedWorldPivot);
	  HK_ASSERT(0xdee884, physV.isOk<4>());
  }
示例#2
0
void DebugDrawManager::add_quad(const hkVector4& center, float width, float height, uint32_t color, bool bDepth)
{
    float x = center.getSimdAt(0);
    float y = center.getSimdAt(1);
    float z = center.getSimdAt(2);
    hkVector4 v0, v1, v2, v3;
    v0.set(x-width/2, y, z-height/2);
    v1.set(x+width/2, y, z-height/2);
    v2.set(x+width/2, y, z+height/2);
    v3.set(x-width/2, y, z+height/2);
    add_line(v0, v1, color, bDepth);
    add_line(v1, v2, color, bDepth);
    add_line(v2, v3, color, bDepth);
    add_line(v3, v0, color, bDepth);
}
  ///
  /// \brief
  ///   Get a Havok Physics object space/scalar vector from a Vision vector; taking Vision scaling into account.
  ///
  VHAVOK_IMPEXP static HK_FORCE_INLINE void VisVecToPhysVecLocal(const hkvVec3& visV, hkVector4& physV)
  {
	  physV.load<3, HK_IO_NATIVE_ALIGNED>(&visV.data[0]);
	  physV.zeroComponent<3>();
	  physV.mul(m_cachedVis2PhysScale);
	  HK_ASSERT(0xdee883, physV.isOk<4>());
  }
示例#4
0
void DemoKeeper::getKeyframePositionAndRotation( hkReal t, hkVector4& pos, hkQuaternion& rot )
{
	t *= 2 * HK_REAL_PI * m_speed;
	pos.set(m_radius * hkMath::cos(t), 10-2.0f, -m_radius * hkMath::sin(t));

	hkVector4 axis(0,1,0);
	rot.setAxisAngle(axis, t);
}
// Apply a force which is scaled depending on whether or not it's our character controller.
// The character controller's special gravity implementation means that it needs a greater
//  force to get the same effect.
void PlanetGravityDemo::applyScaledLinearImpulse( hkpRigidBody* rb, hkVector4& impulse )
{
	if( rb != m_characterRigidBody->getRigidBody() )
	{
		impulse.mul4( 0.3f );
	}

	rb->applyLinearImpulse( impulse );
}
  ///
  /// \brief
  ///   Get a Havok Physics object space/scalar vector from a Vision vector; taking Vision scaling into account.
  ///
  VHAVOK_IMPEXP static HK_FORCE_INLINE void VisVecToPhysVecLocal(const hkvVec3d& visV, hkVector4& physV)
  {
	  /*! Work around, see [SIM-41] */
	  AlignedArray array(visV);

	  physV.load<3, HK_IO_NATIVE_ALIGNED>(array.m_array);
	  physV.zeroComponent<3>();
	  physV.mul(m_cachedVis2PhysScale);
	  HK_ASSERT(0xdee883, physV.isOk<4>());
  }
bool PlayerUIDialog::GetClosestPointOnNavMeshUnderCursor(hkVector4& point, hkVector4 const& searchPoint)
{
  IVGUIContext *const context = GetContext();
  VASSERT(context);
  hkvVec2 const mousePos = GetCursorPosition(context);

  hkvVec3 traceDirOut;
  VisRenderContext_cl::GetCurrentContext()->GetTraceDirFromScreenPos(mousePos.x, mousePos.y, traceDirOut, 1.0f);
  hkvVec3 const& camPos = VisRenderContext_cl::GetCurrentContext()->GetCamera()->GetPosition();

  hkVector4 rayStartHavok, rayEndHavok;
  RPG_VisionHavokConversion::VisionToHavokPoint(camPos, rayStartHavok);
  RPG_VisionHavokConversion::VisionToHavokPoint(camPos + traceDirOut * 5000.0f, rayEndHavok);

  hkaiNavMeshQueryMediator::HitDetails hit;
  if(vHavokAiModule::GetInstance()->GetAiWorld()->getDynamicQueryMediator()->castRay(rayStartHavok, rayEndHavok, hit))
  {
    point.setInterpolate(rayStartHavok, rayEndHavok, hit.m_hitFraction);
    return true;
  }
  else
  {
    // If the ray missed the nav mesh:
    // 1. Find the nav mesh face closest to the search point
    // 2. Intersect the ray with the plane of this face
    // 3. Find the closest point on the nav mesh to the plane point
    hkVector4 dummyPoint;
    hkaiPackedKey const searchFaceKey = 
      vHavokAiModule::GetInstance()->GetAiWorld()->getDynamicQueryMediator()->getClosestPoint(searchPoint, 1.f, dummyPoint);
    if(searchFaceKey != HKAI_INVALID_PACKED_KEY)
    {
      hkVector4 facePlane;
      hkaiNavMeshInstance const *meshInstance = vHavokAiModule::GetInstance()->GetAiWorld()->getStreamingCollection()->getInstanceAt(hkaiGetRuntimeIdFromPacked(searchFaceKey));
      {
        hkaiNavMeshUtils::calcFacePlane(*meshInstance, hkaiGetIndexFromPacked(searchFaceKey), facePlane);
      }

      hkSimdReal const f = facePlane.dot4xyz1(rayStartHavok);
      hkSimdReal const t = facePlane.dot4xyz1(rayEndHavok);
      if(f.isGreaterEqualZero() && t.isLessZero())
      {
        hkVector4 planePoint;
        {
          hkSimdReal const hitFraction = f / (f - t);
          planePoint.setInterpolate(rayStartHavok, rayEndHavok, hitFraction);
        }

        hkaiPackedKey faceKey = vHavokAiModule::GetInstance()->GetAiWorld()->getDynamicQueryMediator()->getClosestPoint(planePoint, 5.f, point);
        return (faceKey != HKAI_INVALID_PACKED_KEY);
      }
    }
  }

  return false;
}
示例#8
0
	// little ik
void SpiderDemo::doLegIk( const SpiderDemo::calcLegMatrizesIn& in, hkVector4& pivotOut, hkRotation& mAOut, hkRotation& mBOut )
{
	hkVector4 dir; dir.setSub4( in.m_to, in.m_from );
	hkReal tdist = dir.length3();
	if ( tdist >= in.m_lenA + in.m_lenB )
	{
		hkVector4Util::buildOrthonormal( dir, in.m_up, mAOut );
		mBOut = mAOut;
		dir.normalize3();
		pivotOut.setAddMul4( in.m_from, dir, in.m_lenA );
		return;
	}
	dir.normalize3();
	hkReal la2 = in.m_lenA*in.m_lenA;
	hkReal lb2 = in.m_lenB*in.m_lenB;
	hkReal adist = 0.5f * (la2- lb2 + tdist*tdist) / tdist;
	hkReal hdist = hkMath::sqrt( la2 - adist*adist );

	hkVector4 cup;
	{
		hkVector4 h; h.setCross( dir, in.m_up );
		cup.setCross( h, dir );
		cup.normalize3();
	}

	{
		pivotOut.setAddMul4( in.m_from, dir, adist );
		pivotOut.addMul4( hdist, cup );
	}

	{
		hkVector4 d; d.setSub4( pivotOut, in.m_from );
		d.normalize3();
		hkVector4Util::buildOrthonormal( d, in.m_up, mAOut );
	}
	{
		hkVector4 d; d.setSub4( in.m_to, pivotOut );
		d.normalize3();
		hkVector4Util::buildOrthonormal( d, in.m_up, mBOut );
	}
}
void DestructibleWallsDemo::posOnGround(hkpWorld* world, const hkVector4& pos, hkVector4& newPos) const 
{
	// cast a ray to find exact position
	hkpWorldRayCastInput ray;
	ray.m_from = pos;
	ray.m_to = pos;
	ray.m_from(1) += 20.0f;
	ray.m_to(1) -= 20.0f;
	hkpWorldRayCastOutput rayOutput;
	world->castRay(ray,rayOutput);

	newPos.setInterpolate4(ray.m_from, ray.m_to, rayOutput.m_hitFraction);
}
示例#10
0
void DiskEmissionUtil::samplePosition(hkVector4& position, hkPseudoRandomGenerator* pseudoRandomGenerator) const
{
	// Pick a random point on the disk (see http://mathworld.wolfram.com/DiskPointPicking.html)
	hkReal radius = m_radius * hkMath::sqrt(pseudoRandomGenerator->getRandReal01());
	hkReal theta = pseudoRandomGenerator->getRandReal01() * 2.f * HK_REAL_PI;
	hkReal diskX = radius * hkMath::cos(theta);
	hkReal diskY = radius * hkMath::sin(theta);

	hkReal offsetX = pseudoRandomGenerator->getRandRange(-m_outOfPlaneVariance, m_outOfPlaneVariance);
	hkReal offsetY = diskY + pseudoRandomGenerator->getRandRange(-m_inPlaneVariance, m_inPlaneVariance);
	hkReal offsetZ = diskX + pseudoRandomGenerator->getRandRange(-m_inPlaneVariance, m_inPlaneVariance);
	hkVector4 localOffset(offsetX, offsetY, offsetZ);

	m_orthonormalBasis.multiplyVector(localOffset, position);
	position.add4(m_position);
}
示例#11
0
void DebugDrawManager::add_aabb( const hkVector4& min, const hkVector4& max, uint32_t color, bool bDepth)
{
    hkVector4 start, end;
    //1.
    start.set(min.getSimdAt(0), min.getSimdAt(1), min.getSimdAt(2));
    end.set(max.getSimdAt(0), min.getSimdAt(1), min.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //2.
    start.set(max.getSimdAt(0), min.getSimdAt(1), min.getSimdAt(2));
    end.set(max.getSimdAt(0), max.getSimdAt(1), min.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //3.
    start.set(max.getSimdAt(0), max.getSimdAt(1), min.getSimdAt(2));
    end.set(min.getSimdAt(0), max.getSimdAt(1), min.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //4.
    start.set(min.getSimdAt(0), max.getSimdAt(1), min.getSimdAt(2));
    end.set(min.getSimdAt(0), min.getSimdAt(1), min.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //5.
    start.set(min.getSimdAt(0), min.getSimdAt(1), min.getSimdAt(2));
    end.set(min.getSimdAt(0), min.getSimdAt(1), max.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //6.
    start.set(max.getSimdAt(0), min.getSimdAt(1), min.getSimdAt(2));
    end.set(max.getSimdAt(0), min.getSimdAt(1), max.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //7.
    start.set(max.getSimdAt(0), max.getSimdAt(1), min.getSimdAt(2));
    end.set(max.getSimdAt(0), max.getSimdAt(1), max.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //8.
    start.set(min.getSimdAt(0), max.getSimdAt(1), min.getSimdAt(2));
    end.set(min.getSimdAt(0), max.getSimdAt(1), max.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //9.
    start.set(min.getSimdAt(0), min.getSimdAt(1), max.getSimdAt(2));
    end.set(max.getSimdAt(0), min.getSimdAt(1), max.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //10.
    start.set(max.getSimdAt(0), min.getSimdAt(1), max.getSimdAt(2));
    end.set(max.getSimdAt(0), max.getSimdAt(1), max.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //11.
    start.set(max.getSimdAt(0), max.getSimdAt(1), max.getSimdAt(2));
    end.set(min.getSimdAt(0), max.getSimdAt(1), max.getSimdAt(2));
    add_line(start, end, color, bDepth);
    //12.
    start.set(min.getSimdAt(0), max.getSimdAt(1), max.getSimdAt(2));
    end.set(min.getSimdAt(0), min.getSimdAt(1), max.getSimdAt(2));
    add_line(start, end, color, bDepth);
}
示例#12
0
static void SetTransformPosition(hkQsTransform& transform, hkVector4& p)
{
    if (p.getSimdAt(0) != FloatNegINF) transform.setTranslation(p);
}
示例#13
0
void AabbSpawnUtil::getNewSpawnPosition(const hkVector4& aabbDims, hkVector4& positionOut)
{
	// Try each volume in turn
	while (1)
	{
		hkVector4 avaliableDiag; avaliableDiag.setSub4( m_spawnVolumes[m_currentSpawnVolume].m_max, m_spawnVolumes[m_currentSpawnVolume].m_min );
		avaliableDiag.sub4(aabbDims);
		if ( avaliableDiag(0) < 0  || avaliableDiag(2) < 0 )
		{
			HK_ASSERT2(0, 0, "No spawn space large enough for requested aabb");
			return;
		}

		// Try 100 random positions in the volume
		int numTries = m_allowOverlaps ? 1 : 100;
		for (int j = 0; j < numTries; ++j)
		{
			hkVector4 minPos(m_pseudoRandomGenerator.getRandReal01(), m_pseudoRandomGenerator.getRandReal01(), m_pseudoRandomGenerator.getRandReal01() );
			
			if (avaliableDiag(1) < 0)
			{
				minPos(1) = 0;
			}

			minPos.mul4(avaliableDiag);
			minPos.add4(m_spawnVolumes[m_currentSpawnVolume].m_min);


			hkVector4 maxPos; maxPos.setAdd4( minPos, aabbDims );
			hkAabb candidate( minPos, maxPos );
			bool aabbCollides = false;

			if (!m_allowOverlaps)
			{
				for ( int k = 0; k < m_spawnedAabbs[m_currentSpawnVolume].getSize(); k++ )
				{
					if ( m_spawnedAabbs[m_currentSpawnVolume][k].overlaps(candidate))
					{
						aabbCollides = true;
						break;
					}
				}
			}
			if ( !aabbCollides )
			{
				m_spawnedAabbs[m_currentSpawnVolume].pushBack(candidate);
				hkVector4 position; positionOut.setInterpolate4( candidate.m_min, candidate.m_max, .5f );

				// If we allow penetrations, take each spawn volume in turn
				if ( m_allowOverlaps )
				{
					m_currentSpawnVolume++;
					if (m_currentSpawnVolume == m_spawnVolumes.getSize())
					{
						m_currentSpawnVolume = 0;
					}
				}
				return;
			}
		}
		// If we couldn't find a space, try the next volume
		m_currentSpawnVolume++;
		if (m_currentSpawnVolume == m_spawnVolumes.getSize())
		{
			m_currentSpawnVolume = 0;
			m_allowOverlaps = true;
		}
	}
}