0ad/source/sced/BrushTool.cpp
2004-06-10 22:24:03 +00:00

150 lines
3.3 KiB
C++
Executable File

#include "BrushTool.h"
#include "UIGlobals.h"
#include "HFTracer.h"
#include "NaviCam.h"
#include "TextureManager.h"
#include "Camera.h"
#include "Terrain.h"
#include "Renderer.h"
#include "ogl.h"
#include <list>
extern CCamera g_Camera;
extern CTerrain g_Terrain;
CBrushTool::CBrushTool() : m_BrushSize(1), m_LButtonDown(false), m_RButtonDown(false)
{
}
static void RenderTileOutline(int gx,int gz)
{
CMiniPatch* mpatch=g_Terrain.GetTile(gx,gz);
if (!mpatch) return;
u32 mapSize=g_Terrain.GetVerticesPerSide();
CVector3D V[4];
g_Terrain.CalcPosition(gx,gz,V[0]);
g_Terrain.CalcPosition(gx+1,gz,V[1]);
g_Terrain.CalcPosition(gx+1,gz+1,V[2]);
g_Terrain.CalcPosition(gx,gz+1,V[3]);
glLineWidth(2);
glColor4f(0.05f,0.95f,0.1f,0.75f);
glBegin (GL_LINE_LOOP);
for(int i = 0; i < 4; i++)
glVertex3fv(&V[i].X);
glEnd ();
glColor4f (0.1f,0.9f,0.15f,0.35f);
glBegin (GL_QUADS);
for(i = 0; i < 4; i++)
glVertex3fv(&V[i].X);
glEnd ();
}
void CBrushTool::OnDraw()
{
g_Renderer.SetTexture(0,0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(0);
int r=m_BrushSize;
// iterate through selected patches
for (int j=m_SelectionCentre[1]-r;j<=m_SelectionCentre[1]+r;j++) {
for (int i=m_SelectionCentre[0]-r;i<=m_SelectionCentre[0]+r;i++) {
RenderTileOutline(i,j);
}
}
glDepthMask(1);
glDisable(GL_BLEND);
}
void CBrushTool::OnLButtonDown(unsigned int flags,int px,int py)
{
m_LButtonDown=true;
OnTriggerLeft();
}
void CBrushTool::OnLButtonUp(unsigned int flags,int px,int py)
{
m_LButtonDown=false;
}
void CBrushTool::OnRButtonDown(unsigned int flags,int px,int py)
{
m_RButtonDown=true;
OnTriggerRight();
}
void CBrushTool::OnRButtonUp(unsigned int flags,int px,int py)
{
m_RButtonDown=false;
}
/////////////////////////////////////////////////////////////////////////////////////////
// BuildCameraRay: calculate origin and ray direction of a ray through
// the pixel (px,py) on the screen
void CBrushTool::BuildCameraRay(int px,int py,CVector3D& origin,CVector3D& dir)
{
// get points on far plane of frustum in camera space
CCamera& camera=g_NaviCam.GetCamera();
CVector3D cPts[4];
camera.GetCameraPlanePoints(camera.GetFarPlane(),cPts);
// transform to world space
CVector3D wPts[4];
for (int i=0;i<4;i++) {
wPts[i]=camera.m_Orientation.Transform(cPts[i]);
}
// get world space position of mouse point
float dx=float(px)/float(g_Renderer.GetWidth());
float dz=1-float(py)/float(g_Renderer.GetHeight());
CVector3D vdx=wPts[1]-wPts[0];
CVector3D vdz=wPts[3]-wPts[0];
CVector3D pt=wPts[0]+(vdx*dx)+(vdz*dz);
// copy origin
origin=camera.m_Orientation.GetTranslation();
// build direction
dir=pt-origin;
dir.Normalize();
}
void CBrushTool::OnMouseMove(unsigned int flags,int px,int py)
{
// build camera ray
CVector3D rayorigin,raydir;
BuildCameraRay(px,py,rayorigin,raydir);
// intersect with terrain
CVector3D ipt;
CHFTracer hftracer(g_Terrain.GetHeightMap(),g_Terrain.GetVerticesPerSide(),float(CELL_SIZE),HEIGHT_SCALE);
if (hftracer.RayIntersect(rayorigin,raydir,m_SelectionCentre[0],m_SelectionCentre[1],m_SelectionPoint)) {
// drag trigger supported?
if (SupportDragTrigger()) {
// yes - handle mouse button down state
if (m_LButtonDown) {
OnTriggerLeft();
} else if (m_RButtonDown) {
OnTriggerRight();
}
}
}
}