Modified world intersection so that you can also intersect with the water plane, which is useful for making ships move around as expected when you rightclick a spot on the water.
This was SVN commit r4319.
This commit is contained in:
parent
df1a779d76
commit
aa6ca7d1e8
@ -14,6 +14,7 @@
|
||||
|
||||
#include "Camera.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/WaterManager.h"
|
||||
#include "HFTracer.h"
|
||||
#include "ps/Game.h"
|
||||
#include "lib/ogl.h"
|
||||
@ -201,21 +202,63 @@ void CCamera::GetScreenCoordinates( const CVector3D& world, float& x, float& y )
|
||||
y = ( 1 - y ) * 0.5f * g_Renderer.GetHeight();
|
||||
}
|
||||
|
||||
CVector3D CCamera::GetWorldCoordinates( int px, int py )
|
||||
CVector3D CCamera::GetWorldCoordinates( int px, int py, bool aboveWater )
|
||||
{
|
||||
CHFTracer tracer( g_Game->GetWorld()->GetTerrain() );
|
||||
int x, z;
|
||||
CVector3D origin, dir, delta, currentTarget;
|
||||
CVector3D origin, dir, delta, terrainPoint, waterPoint;
|
||||
|
||||
BuildCameraRay( px, py, origin, dir );
|
||||
|
||||
if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) )
|
||||
return( currentTarget );
|
||||
|
||||
// Off the edge of the world?
|
||||
// Work out where it /would/ hit, if the map were extended out to infinity with average height.
|
||||
bool gotTerrain = tracer.RayIntersect( origin, dir, x, z, terrainPoint );
|
||||
|
||||
if( !aboveWater )
|
||||
{
|
||||
if( gotTerrain )
|
||||
return terrainPoint;
|
||||
|
||||
// Off the edge of the world?
|
||||
// Work out where it /would/ hit, if the map were extended out to infinity with average height.
|
||||
return GetWorldCoordinates( px, py, 50.0f );
|
||||
}
|
||||
|
||||
CPlane plane;
|
||||
plane.Set(CVector3D(0.f, 1.f, 0.f), // upwards normal
|
||||
CVector3D(0.f, g_Renderer.GetWaterManager()->m_WaterHeight, 0.f)); // passes through water plane
|
||||
|
||||
bool gotWater = plane.FindRayIntersection( origin, dir, &waterPoint );
|
||||
|
||||
if( gotTerrain )
|
||||
{
|
||||
if( gotWater )
|
||||
{
|
||||
// Intersecting both heightmap and water plane; choose the closest of those
|
||||
if( (origin - terrainPoint).LengthSquared() < (origin - waterPoint).LengthSquared() )
|
||||
return terrainPoint;
|
||||
else
|
||||
return waterPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Intersecting heightmap but parallel to water plane
|
||||
return terrainPoint;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( gotWater )
|
||||
{
|
||||
// Only intersecting water plane
|
||||
return waterPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not intersecting terrain or water; just return 0,0,0.
|
||||
return CVector3D(0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
return( origin + dir * ( ( 50.0f - origin.Y ) / dir.Y ) );
|
||||
}
|
||||
|
||||
CVector3D CCamera::GetWorldCoordinates(int px, int py, float h)
|
||||
|
@ -77,8 +77,10 @@ class CCamera
|
||||
void GetScreenCoordinates(const CVector3D& world, float& x, float& y) const;
|
||||
|
||||
// Get the point on the terrain corresponding to pixel (px,py) (or the mouse coordinates)
|
||||
CVector3D GetWorldCoordinates(int px, int py);
|
||||
CVector3D GetWorldCoordinates() { return GetWorldCoordinates(g_mouse_x, g_mouse_y); }
|
||||
// The aboveWater parameter determines whether we want to stop at the water plane or also get underwater points
|
||||
CVector3D GetWorldCoordinates(int px, int py, bool aboveWater=false);
|
||||
CVector3D GetWorldCoordinates(bool aboveWater=false)
|
||||
{ return GetWorldCoordinates(g_mouse_x, g_mouse_y, aboveWater); }
|
||||
// Get the point on the plane at height h corresponding to pixel (px,py)
|
||||
CVector3D GetWorldCoordinates(int px, int py, float h);
|
||||
// Get the point on the terrain the camera is pointing towards
|
||||
|
@ -373,7 +373,7 @@ void CGameView::ResetCameraOrientation()
|
||||
|
||||
void CGameView::RotateAboutTarget()
|
||||
{
|
||||
m_CameraPivot = m_ViewCamera.GetWorldCoordinates();
|
||||
m_CameraPivot = m_ViewCamera.GetWorldCoordinates(true);
|
||||
}
|
||||
|
||||
void CGameView::Update(float DeltaTime)
|
||||
|
@ -646,7 +646,7 @@ void CMouseoverEntities::update( float timestep )
|
||||
|
||||
CUnit* hit = g_UnitMan.PickUnit( origin, dir );
|
||||
|
||||
m_worldposition = pCamera->GetWorldCoordinates();
|
||||
m_worldposition = pCamera->GetWorldCoordinates(true);
|
||||
|
||||
if( hit && hit->GetEntity() && hit->GetEntity()->m_extant )
|
||||
{
|
||||
|
@ -847,7 +847,7 @@ jsval CEntity::GetRallyPoint( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval*
|
||||
jsval CEntity::SetRallyPoint( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
|
||||
{
|
||||
entf_set(ENTF_HAS_RALLY_POINT);
|
||||
m_rallyPoint = g_Game->GetView()->GetCamera()->GetWorldCoordinates();
|
||||
m_rallyPoint = g_Game->GetView()->GetCamera()->GetWorldCoordinates(true);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user