⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbillboardcamera.cpp

📁 一个非常有用的开源代码
💻 CPP
字号:
/*	Copyright (C) 2006, Mike Gashler	This library is free software; you can redistribute it and/or	modify it under the terms of the GNU Lesser General Public	License as published by the Free Software Foundation; either	version 2.1 of the License, or (at your option) any later version.	see http://www.gnu.org/copyleft/lesser.html*/#include "GBillboardCamera.h"#include <math.h>void GBillboardCamera::SetDirection(float radians){	m_direction = radians;	m_cosDirection = (float)cos(radians);	m_sinDirection = (float)sin(radians);}void GBillboardCamera::SetPos(float x, float y){	m_x = x;	m_y = y;	Backup(m_backup);}void GBillboardCamera::MapToScreen(float* pOutX, float* pOutY, float* pOutScale, float x, float y, float z, GRect* pScreenRect){	float t;	// Ajust for camera position	x -= m_x;	y -= m_y;	// Ajust for Yaw	t = x * m_cosDirection + y * m_sinDirection;	y = y * m_cosDirection - x * m_sinDirection;	x = t;	// Scale relative to distance from camera	y *= (m_horizonHeight / (m_horizonHeight + y));	t = (float)1 - (y / m_horizonHeight);	t *= m_zoom;	y *= m_zoom;	x *= t;	z *= t;	// Ajust for camera height	z -= (m_z + m_vertajust);	// Calculate literal screen rect	*pOutX = x + pScreenRect->x + (pScreenRect->w >> 1);	*pOutY = pScreenRect->y + pScreenRect->h - y - z;	*pOutScale = t;}void GBillboardCamera::ScreenToMap(float* px, float* py, float* pSize, bool* pbSky, int xScr, int yScr, GRect* pScreenRect, int nSkyImageWidth){	xScr -= pScreenRect->x;	yScr -= pScreenRect->y;	yScr = pScreenRect->h - yScr + (int)(m_z + m_vertajust);	xScr -= (pScreenRect->w >> 1);	float horiz = m_horizonHeight * m_zoom;	if(yScr > horiz)	{		*pbSky = true;		*px = xScr - m_direction * nSkyImageWidth / ((float)3.14159265359 * 2);		*py = yScr - horiz + 1;		*pSize = 1;	}	else	{		float x, y, t;		*pbSky = false;		t = m_zoom * ((float)1 - (yScr / horiz));		x = xScr / t;		y = yScr / t;		*pSize = t;		// Ajust for yaw		t = x * m_cosDirection - y * m_sinDirection;		y = y * m_cosDirection + x * m_sinDirection;		x = t;		// Ajust for camera position		*px = x + m_x;		*py = y + m_y;	}}void GBillboardCamera::CalcBillboardRect(GRect* pOutRect, GPosSize* pPosSize, GRect* pScreenRect, int nPivotHeight){	float x, y, scale;	float wid = m_cosDirection * m_cosDirection * pPosSize->sx + m_sinDirection * m_sinDirection * pPosSize->sy;	float hgt = pPosSize->sz;	MapToScreen(&x, &y, &scale, pPosSize->x, pPosSize->y, pPosSize->z, pScreenRect);	wid *= scale;	hgt *= scale;	pOutRect->x = (int)(x - wid / 2);	pOutRect->y = (int)(y - hgt) + (int)(nPivotHeight * scale);	pOutRect->w = (int)wid;	pOutRect->h = (int)hgt;}void GBillboardCamera::CalcPanelTrapezoid(GPanelPos* pOutPos, GPosSize* pPosSize, GRect* pScreenRect){	// Calculate bounding points	float x1, y1, scale1, x2, y2, scale2;	float hdx = pPosSize->sx / 2;	float hdy = pPosSize->sy / 2;	MapToScreen(&x1, &y1, &scale1, pPosSize->x - hdx, pPosSize->y - hdy, pPosSize->z, pScreenRect);	MapToScreen(&x2, &y2, &scale2, pPosSize->x + hdx, pPosSize->y + hdy, pPosSize->z, pScreenRect);	if(x1 < x2)	{		pOutPos->w = x2 - x1;		pOutPos->h = pPosSize->sz * scale1;		pOutPos->x = x1;		pOutPos->y = y1 - pOutPos->h;		pOutPos->dy = ((y2 - (pPosSize->sz * scale2)) - pOutPos->y) / pOutPos->w;		pOutPos->dh = (pPosSize->sz * (scale2 - scale1)) / pOutPos->w;	}	else	{		pOutPos->w = x1 - x2;		pOutPos->h = pPosSize->sz * scale2;		pOutPos->x = x2;		pOutPos->y = y2 - pOutPos->h;		pOutPos->dy = ((y1 - (pPosSize->sz * scale1)) - pOutPos->y) / pOutPos->w;		pOutPos->dh = (pPosSize->sz * (scale1 - scale2)) / pOutPos->w;	}	if(scale1 < 0 || scale2 < 0)		pOutPos->w = 0;}float GBillboardCamera::CalculateDistanceFromCamera(float x, float y){	// Ajust for camera position	x -= m_x;	y -= m_y;	// Ajust for Yaw	y = y * m_cosDirection - x * m_sinDirection;	return y;}// We don't want the camera immediately behind the avatar's head, so// let's back it up a bit in the opposite direction that we're facingvoid GBillboardCamera::Backup(float distance){	m_y -= (m_cosDirection * distance);	m_x += (m_sinDirection * distance);}void GBillboardCamera::Move(float dx, float dy){	m_x += dx * m_cosDirection;	m_y += dx * m_sinDirection;	m_x -= dy * m_sinDirection;	m_y += dy * m_cosDirection;}void GBillboardCamera::RecalcVertAjust(int nScreenVerticalCenter){	// Move the camera vertically until the avatar is at the center of the screen	m_vertajust = m_backup * (m_horizonHeight / (m_horizonHeight + m_backup)) * m_zoom - nScreenVerticalCenter;}void GBillboardCamera::AjustZoom(float fac, int nScreenVerticalCenter){	// Disallow excessive zooming	if(fac > 1)	{		if(m_zoom > 1.4)			return;	}	else	{		if(m_zoom < .4)			return;	}	// Ajust the zoom	m_zoom *= fac;	// Move the camera farther away when zoomed out.  (This combination of zoom and moving	// the camera seems to give the user a more useful control of the view than either of	// them alone.)	m_backup = (float)500 / m_zoom;	RecalcVertAjust(nScreenVerticalCenter);}void GBillboardCamera::AjustHorizonHeight(float factor, int nScreenVerticalCenter){	if(factor > 1)	{		if(m_horizonHeight > 10000)			return;	}	else	{		if(m_horizonHeight < 100)			return;	}	m_horizonHeight *= factor;	RecalcVertAjust(nScreenVerticalCenter);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -