527 lines
12 KiB
C++
527 lines
12 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Engine Source File.
|
|
// Copyright (C), Crytek Studios, 2001.
|
|
// -------------------------------------------------------------------------
|
|
// File name: TagPoint.cpp
|
|
// Version: v1.00
|
|
// Created: 10/10/2001 by Timur.
|
|
// Compilers: Visual C++ 6.0
|
|
// Description: CCameraObject implementation.
|
|
// -------------------------------------------------------------------------
|
|
// History:
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "StdAfx.h"
|
|
#include "CameraObject.h"
|
|
#include "ObjectManager.h"
|
|
#include "..\Viewport.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CBase implementation.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
IMPLEMENT_DYNCREATE(CCameraObject,CEntity)
|
|
IMPLEMENT_DYNCREATE(CCameraObjectTarget,CEntity)
|
|
|
|
#define CAMERA_COLOR RGB(0,255,255)
|
|
#define CAMERA_CONE_LENGTH 4
|
|
#define CAMERABOX_RADIUS 0.7f
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CCameraObject::CCameraObject()
|
|
{
|
|
mv_fov = DEG2RAD(60.0f);
|
|
m_creationStep = 0;
|
|
SetColor(CAMERA_COLOR);
|
|
|
|
AddVariable( mv_fov,"FOV",functor(*this,&CCameraObject::OnFovChange),IVariable::DT_ANGLE );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::Done()
|
|
{
|
|
CBaseObjectPtr lookat = GetLookAt();
|
|
|
|
CEntity::Done();
|
|
|
|
if (lookat)
|
|
{
|
|
// If look at is also camera class, delete lookat target.
|
|
if (lookat->IsKindOf(RUNTIME_CLASS(CCameraObjectTarget)))
|
|
GetObjectManager()->DeleteObject( lookat );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CCameraObject::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
|
{
|
|
bool res = CEntity::Init( ie,prev,file );
|
|
|
|
m_entityClass = "CameraSource";
|
|
|
|
if (prev)
|
|
{
|
|
CBaseObjectPtr prevLookat = prev->GetLookAt();
|
|
if (prevLookat)
|
|
{
|
|
CBaseObjectPtr lookat = GetObjectManager()->NewObject( prevLookat->GetClassDesc(),prevLookat );
|
|
if (lookat)
|
|
{
|
|
lookat->SetPos( prevLookat->GetPos() + Vec3(3,0,0) );
|
|
GetObjectManager()->ChangeObjectName( lookat,CString(GetName()) + " Target" );
|
|
SetLookAt( lookat );
|
|
}
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void CCameraObject::Serialize( CObjectArchive &ar )
|
|
{
|
|
CEntity::Serialize( ar );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
IAnimNode* CCameraObject::CreateAnimNode()
|
|
{
|
|
int nodeId = GetId().Data1;
|
|
IAnimNode *animNode = GetIEditor()->GetMovieSystem()->CreateNode( ANODE_CAMERA,nodeId );
|
|
//IAnimNode *animNode = CEntity::CreateAnimNode();
|
|
if (animNode)
|
|
{
|
|
float fov = mv_fov;
|
|
animNode->SetParamValue( 0,APARAM_FOV,RAD2DEG(fov) );
|
|
}
|
|
return animNode;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::OnNodeAnimated()
|
|
{
|
|
assert( m_animNode != 0 ); // Only can be called if there`s an anim node present.
|
|
|
|
CEntity::OnNodeAnimated();
|
|
// Get fov out of node at current time.
|
|
float fov = RAD2DEG(mv_fov);
|
|
if (m_animNode->GetParamValue( GetIEditor()->GetAnimation()->GetTime(),APARAM_FOV,fov ))
|
|
{
|
|
mv_fov = DEG2RAD(fov);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::SetName( const CString &name )
|
|
{
|
|
CEntity::SetName(name);
|
|
if (GetLookAt())
|
|
{
|
|
GetLookAt()->SetName( CString(GetName()) + " Target" );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::SetScale( const Vec3d &scale )
|
|
{
|
|
// Ignore scale.
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::BeginEditParams( IEditor *ie,int flags )
|
|
{
|
|
// Skip entity begin edit params.
|
|
CBaseObject::BeginEditParams( ie,flags );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::EndEditParams( IEditor *ie )
|
|
{
|
|
// Skip entity end edit params.
|
|
CBaseObject::EndEditParams( ie );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
int CCameraObject::MouseCreateCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags )
|
|
{
|
|
if (event == eMouseMove || event == eMouseLDown || event == eMouseLUp)
|
|
{
|
|
Vec3 pos;
|
|
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
|
{
|
|
pos = view->MapViewToCP(point);
|
|
}
|
|
else
|
|
{
|
|
// Snap to terrain.
|
|
bool hitTerrain;
|
|
pos = view->ViewToWorld( point,&hitTerrain );
|
|
if (hitTerrain)
|
|
{
|
|
pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y) + 1.0f;
|
|
}
|
|
pos = view->SnapToGrid(pos);
|
|
}
|
|
|
|
if (m_creationStep == 1)
|
|
{
|
|
if (GetLookAt())
|
|
{
|
|
GetLookAt()->SetPos( pos );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetPos(pos);
|
|
}
|
|
|
|
if (event == eMouseLDown && m_creationStep == 0)
|
|
{
|
|
m_creationStep = 1;
|
|
}
|
|
if (event == eMouseMove && 1 == m_creationStep && !GetLookAt())
|
|
{
|
|
float d = GetDistance(pos,GetPos());
|
|
if (d*view->GetScreenScaleFactor(pos) > 1)
|
|
{
|
|
// Create LookAt Target.
|
|
GetIEditor()->ResumeUndo();
|
|
CreateTarget();
|
|
GetIEditor()->SuspendUndo();
|
|
}
|
|
}
|
|
if (eMouseLUp == event && 1 == m_creationStep)
|
|
return MOUSECREATE_OK;
|
|
|
|
return MOUSECREATE_CONTINUE;
|
|
}
|
|
return CBaseObject::MouseCreateCallback( view,event,point,flags );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::CreateTarget()
|
|
{
|
|
// Create another camera object for target.
|
|
CCameraObject *camTarget = (CCameraObject*)GetObjectManager()->NewObject( "CameraTarget" );
|
|
if (camTarget)
|
|
{
|
|
camTarget->SetName( CString(GetName()) + " Target" );
|
|
camTarget->SetPos( GetWorldPos() + Vec3(3,0,0) );
|
|
SetLookAt( camTarget );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::Display( DisplayContext &dc )
|
|
{
|
|
const Matrix44 &wtm = GetWorldTM();
|
|
Vec3 wp = wtm.GetTranslationOLD();
|
|
|
|
float fScale = dc.view->GetScreenScaleFactor(wp) * 0.03f;
|
|
|
|
if (GetLookAt())
|
|
{
|
|
// Look at camera.
|
|
if (IsFrozen())
|
|
dc.SetFreezeColor();
|
|
else
|
|
dc.SetColor( GetColor() );
|
|
|
|
bool bSelected = IsSelected();
|
|
|
|
if (bSelected || GetLookAt()->IsSelected())
|
|
{
|
|
dc.SetSelectedColor();
|
|
}
|
|
|
|
// Line from source to target.
|
|
dc.DrawLine( wp,GetLookAt()->GetWorldPos() );
|
|
|
|
if (bSelected)
|
|
{
|
|
dc.SetSelectedColor();
|
|
}
|
|
else if (IsFrozen())
|
|
dc.SetFreezeColor();
|
|
else
|
|
dc.SetColor( GetColor() );
|
|
|
|
dc.PushMatrix( wtm );
|
|
|
|
Vec3 sz(0.2f*fScale,0.1f*fScale,0.2f*fScale);
|
|
dc.DrawWireBox( -sz,sz );
|
|
|
|
float dist = 1.0f;
|
|
if (bSelected)
|
|
{
|
|
dist = GetDistance(GetLookAt()->GetWorldPos(),wtm.GetTranslationOLD());
|
|
DrawCone( dc,dist );
|
|
}
|
|
else
|
|
{
|
|
DrawCone( dc,dist,fScale );
|
|
}
|
|
dc.PopMatrix();
|
|
}
|
|
else
|
|
{
|
|
// Free camera
|
|
if (IsSelected())
|
|
dc.SetSelectedColor();
|
|
else if (IsFrozen())
|
|
dc.SetFreezeColor();
|
|
else
|
|
dc.SetColor( GetColor() );
|
|
|
|
dc.PushMatrix( wtm );
|
|
|
|
Vec3 sz(0.2f*fScale,0.1f*fScale,0.2f*fScale);
|
|
dc.DrawWireBox( -sz,sz );
|
|
|
|
float dist = CAMERA_CONE_LENGTH;
|
|
DrawCone( dc,dist,fScale );
|
|
dc.PopMatrix();
|
|
}
|
|
|
|
//dc.DrawIcon( ICON_QUAD,wp,0.1f*dc.view->GetScreenScaleFactor(wp) );
|
|
|
|
DrawDefault( dc );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CCameraObject::HitTest( HitContext &hc )
|
|
{
|
|
Vec3 origin = GetWorldPos();
|
|
float radius = CAMERABOX_RADIUS/2.0f;
|
|
|
|
float fScale = hc.view->GetScreenScaleFactor(origin) * 0.03f;
|
|
|
|
Vec3 w = origin - hc.raySrc;
|
|
w = hc.rayDir.Cross( w );
|
|
float d = w.Length();
|
|
|
|
if (d < radius*fScale + hc.distanceTollerance)
|
|
{
|
|
hc.dist = GetDistance(hc.raySrc,origin);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CCameraObject::HitTestRect( HitContext &hc )
|
|
{
|
|
// transform all 8 vertices into world space
|
|
CPoint p = hc.view->WorldToView( GetWorldPos() );
|
|
if (hc.rect.PtInRect(p))
|
|
{
|
|
hc.object = this;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::GetBoundBox( BBox &box )
|
|
{
|
|
Vec3 pos = GetWorldPos();
|
|
float r;
|
|
r = 1;
|
|
box.min = pos - Vec3(r,r,r);
|
|
box.max = pos + Vec3(r,r,r);
|
|
if (GetLookAt())
|
|
{
|
|
box.Add( GetLookAt()->GetWorldPos() );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::GetLocalBounds( BBox &box )
|
|
{
|
|
GetBoundBox( box );
|
|
Matrix44 invTM( GetWorldTM() );
|
|
invTM.Invert44();
|
|
box.Transform( invTM );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
float CCameraObject::GetFOV() const
|
|
{
|
|
return mv_fov;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
float CCameraObject::GetAspect() const
|
|
{
|
|
return 1.0f;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::GetConePoints( Vec3 q[4],float dist )
|
|
{
|
|
if (dist > 1e8f)
|
|
dist = 1e8f;
|
|
float ta = (float)tan(0.5f*GetFOV());
|
|
float w = dist * ta;
|
|
// float h = w * (float).75; // ASPECT ??
|
|
float h = w / GetAspect();
|
|
|
|
//q[0] = Vec3( w, h,-dist);
|
|
//q[1] = Vec3(-w, h,-dist);
|
|
//q[2] = Vec3(-w,-h,-dist);
|
|
//q[3] = Vec3( w,-h,-dist);
|
|
|
|
q[0] = Vec3( w,-dist, h);
|
|
q[1] = Vec3(-w,-dist, h);
|
|
q[2] = Vec3(-w,-dist,-h);
|
|
q[3] = Vec3( w,-dist,-h);
|
|
}
|
|
|
|
void CCameraObject::DrawCone( DisplayContext &dc,float dist,float fScale )
|
|
{
|
|
Vec3 q[4];
|
|
GetConePoints(q,dist);
|
|
|
|
q[0] *= fScale;
|
|
q[1] *= fScale;
|
|
q[2] *= fScale;
|
|
q[3] *= fScale;
|
|
|
|
Vec3 org(0,0,0);
|
|
dc.DrawLine( org,q[0] );
|
|
dc.DrawLine( org,q[1] );
|
|
dc.DrawLine( org,q[2] );
|
|
dc.DrawLine( org,q[3] );
|
|
|
|
// Draw quad.
|
|
dc.DrawPolyLine( q,4 );
|
|
|
|
// Draw cross.
|
|
//dc.DrawLine( q[0],q[2] );
|
|
//dc.DrawLine( q[1],q[3] );
|
|
}
|
|
|
|
/*
|
|
|
|
void CCameraObject::DrawCone( DisplayContext &dc )
|
|
{
|
|
float dist = 10;
|
|
|
|
Vec3 q[5], u[3];
|
|
GetConePoints(q,dist);
|
|
|
|
if (colid) gw->setColor( LINE_COLOR, GetUIColor(colid));
|
|
if (drawDiags) {
|
|
u[0] = q[0]; u[1] = q[2];
|
|
gw->polyline( 2, u, NULL, NULL, FALSE, NULL );
|
|
u[0] = q[1]; u[1] = q[3];
|
|
gw->polyline( 2, u, NULL, NULL, FALSE, NULL );
|
|
}
|
|
gw->polyline( 4, q, NULL, NULL, TRUE, NULL );
|
|
if (drawSides) {
|
|
gw->setColor( LINE_COLOR, GetUIColor(COLOR_CAMERA_CONE));
|
|
u[0] = Point3(0,0,0);
|
|
for (int i=0; i<4; i++) {
|
|
u[1] = q[i];
|
|
gw->polyline( 2, u, NULL, NULL, FALSE, NULL );
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::OnFovChange( IVariable *var )
|
|
{
|
|
if (m_animNode)
|
|
{
|
|
float fov = mv_fov;
|
|
m_animNode->SetParamValue( GetIEditor()->GetAnimation()->GetTime(),APARAM_FOV, RAD2DEG(fov) );
|
|
}
|
|
}
|
|
|
|
/*
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObject::OnPropertyChange( const CString &property )
|
|
{
|
|
CEntity::OnPropertyChange( property );
|
|
|
|
float fov = m_fov;
|
|
GetParams()->getAttr( "FOV",fov );
|
|
m_fov = fov;
|
|
if (m_animNode)
|
|
m_animNode->SetParam( GetIEditor()->GetAnimation()->GetTime(),APARAM_FOV, fov );
|
|
}
|
|
*/
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CCameraObjectTarget implementation.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CCameraObjectTarget::CCameraObjectTarget()
|
|
{
|
|
SetColor(CAMERA_COLOR);
|
|
}
|
|
|
|
bool CCameraObjectTarget::Init( IEditor *ie,CBaseObject *prev,const CString &file )
|
|
{
|
|
SetColor( CAMERA_COLOR );
|
|
bool res = CEntity::Init( ie,prev,file );
|
|
m_entityClass = "CameraTargetPoint";
|
|
return res;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObjectTarget::Display( DisplayContext &dc )
|
|
{
|
|
Vec3 wp = GetWorldPos();
|
|
|
|
float fScale = dc.view->GetScreenScaleFactor(wp) * 0.03f;
|
|
|
|
if (IsSelected())
|
|
dc.SetSelectedColor();
|
|
else if (IsFrozen())
|
|
dc.SetFreezeColor();
|
|
else
|
|
dc.SetColor( GetColor() );
|
|
|
|
Vec3 sz(0.2f*fScale,0.2f*fScale,0.2f*fScale);
|
|
dc.DrawWireBox( wp-sz,wp+sz );
|
|
|
|
DrawDefault( dc );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CCameraObjectTarget::HitTest( HitContext &hc )
|
|
{
|
|
Vec3 origin = GetWorldPos();
|
|
float radius = CAMERABOX_RADIUS/2.0f;
|
|
|
|
float fScale = hc.view->GetScreenScaleFactor(origin) * 0.03f;
|
|
|
|
Vec3 w = origin - hc.raySrc;
|
|
w = hc.rayDir.Cross( w );
|
|
float d = w.Length();
|
|
|
|
if (d < radius*fScale + hc.distanceTollerance)
|
|
{
|
|
hc.dist = GetDistance(hc.raySrc,origin);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CCameraObjectTarget::GetBoundBox( BBox &box )
|
|
{
|
|
Vec3 pos = GetWorldPos();
|
|
float r = CAMERABOX_RADIUS;
|
|
box.min = pos - Vec3(r,r,r);
|
|
box.max = pos + Vec3(r,r,r);
|
|
}
|
|
|
|
void CCameraObjectTarget::Serialize( CObjectArchive &ar )
|
|
{
|
|
CEntity::Serialize( ar );
|
|
} |