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

📄 gsphereimage.h

📁 一个非常有用的开源代码
💻 H
字号:
/*	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*/#ifndef __GSPHEREIMAGE_H__#define __GSPHEREIMAGE_H__#include "GMacros.h"#include <math.h>#include "GBezier.h"#include "GImage.h"#include "GRayTrace.h"
class GSphereImagePixelEnumerator;class QImage;class GImage;class G3DObject;class GRayTraceVector;
// Represents a spherical image with pixels evenly distributed on the surface of the sphereclass GSphereImage{friend class GSphereImagePixelEnumerator;protected:	int m_nQuarterGirth;	double m_dHalfGirth;	double m_dRadius;	double m_dTheta;	int m_nWidth;	int m_nHeight;public:	GSphereImage(int nQuarterGirth); // nQuarterGirth is one fourth the circumference of the sphere	virtual ~GSphereImage();	// returns one fourth the circumference of the sphere		int GetQuarterGirth()	{		return m_nQuarterGirth;	}	// Returns the width of the flattened image that textures the sphere	int GetWidth()	{		return m_nWidth;	}	// Returns the height of the flattened image that textures the sphere	int GetHeight()	{		return m_nHeight;	}	// Returns the radius of the sphere	double GetRadius()	{		return m_dRadius;	}	// Returns the angle between ajacent pixels	double GetTheta()	{		return m_dTheta;	}	inline static void WrapRadians(double& yaw, double& pitch, bool* pbVertFlip)	{		if(pitch >= 3 * PI / 2)			pitch -= ((2 * PI) * (int)((pitch + PI / 2) / (2 * PI)));		if(pitch < -PI / 2)			pitch += ((2 * PI) * (int)((3 * PI / 2 - pitch) / (2 * PI)));		if(pitch > PI / 2)		{			pitch = PI - pitch;			yaw += PI;			*pbVertFlip = true;		}		else			*pbVertFlip = false;		if(yaw >= 3 * PI / 2)			yaw -= ((2 * PI) * (int)((yaw + PI / 2) / (2 * PI)));		if(yaw < -PI / 2)			yaw += ((2 * PI) * (int)((3 * PI / 2 - yaw) / (2 * PI)));	}	// This expects pitch to be between -PI/2 and PI/2 (inclusively), and yaw to be between -PI/2 to 3*PI/2 (inclusively)	void GetFlattenedCoords(double yaw, double pitch, double* pdX, double* pdY);	void SafeGetFlattenedCoords(double yaw, double pitch, double* pdX, double* pdY);	// This expects nX and nY to be somewhere on the flat image	void GetSphereCoords(int nX, int nY, double* pyaw, double* ppitch);protected:	inline void ToFlat(double yaw, double pitch, double* pdX, double* pdY)	{		*pdY = (pitch * m_dHalfGirth) / PI;		*pdX = (cos(pitch) * yaw * m_dHalfGirth) / PI;	}	inline void ToSphere(int nX, int nY, double* pyaw, double* ppitch)	{		*ppitch = (PI * (double)nY) / m_dHalfGirth;		*pyaw = (PI * (double)nX) / (cos(*ppitch) * m_dHalfGirth);	}};// This class iterates through the pixels in a GSphereImageclass GSphereImagePixelEnumerator{protected:	GSphereImage* m_pSphere;	int m_nX;	int m_nY;	int m_nFrontLeft;	int m_nFrontRight;	int m_nBackLeft;	int m_nBackRight;public:	GSphereImagePixelEnumerator(GSphereImage* pSphere)	{		m_pSphere = pSphere;		Reset();	}	void Reset()	{		m_nX = 0;		m_nY = 0;		RecalculateBounds();	}	bool GetNext(int* pnX, int* pnY);protected:	void RecalculateBounds();};class GPreRendered3DScreen : public GSphereImage{protected:	GImage* m_pImage;	float* m_pDepthMap;	struct Transform m_camera;	double m_dZoom;	bool m_bFlatScreen;public:	GPreRendered3DScreen(int nSize);	virtual ~GPreRendered3DScreen();	GImage* GetFlatImage()	{		return m_pImage;	}	float* GetDepthMap()	{		return m_pDepthMap;	}	// These values are expressed in radians and can be in any range	void SetCameraAngle(const struct Transform* pCamera, bool bFlatScreen);	// x, and y are relative to the center of the screen	void ScreenPixelToSphereCoords(int x, int y, double* pyaw, double* ppitch);	// x, and y are relative to the center of the screen	unsigned int GetPixel(int x, int y, float* pDepth);};class GPreRendered3DSprite : public GSphereImage{protected:	GImage* m_pImages;	float* m_pDepthMap;	int m_nArraySize;	int* m_pArray;	int m_nImageSize;public:	// Note: This will allocate a GImage, but it will not resize it.  It is your	//       job to call GetImages and resize the object it returns as appropriate	//       before you put pixels in it.  I realize that makes this a wierd class,	//       but it suits my purposes for now.	GPreRendered3DSprite(int nSize, int nImageSize);	virtual ~GPreRendered3DSprite();	GImage* GetImages()	{		return m_pImages;	}	float* GetDepthMap()	{		return m_pDepthMap;	}	int GetArraySize()	{		return m_nArraySize;	}	// Returns the width or height of a single image (they're always square)	int GetImageSize()	{		return m_nImageSize;	}	// Pass in coordinates on the flattened sphere image and this will return	// the horizontal offset where the corresponding frame begins in m_pImages.	int GetVertOffset(int nX, int nY)	{		int nIndex = nY * m_nWidth + nX;		GAssert(nIndex >= 0 && nIndex < m_nArraySize, "out of range");		return m_pArray[nIndex];	}	int GetVertOffset(double yaw, double pitch)	{		double nX, nY;		GetFlattenedCoords(yaw, pitch, &nX, &nY);		return GetVertOffset((int)nX, (int)nY);	}	int SafeGetVertOffset(double yaw, double pitch, bool* pbVertFlip)	{		WrapRadians(yaw, pitch, pbVertFlip);		double nX, nY;		GetFlattenedCoords(yaw, pitch, &nX, &nY);		return GetVertOffset((int)nX, (int)nY);	}};class GBoxScene{protected:	GImage m_image;	float* m_pDepthMap;public:	GBoxScene(int nWidth)	{		m_image.SetSize(nWidth, 6 * nWidth);		m_pDepthMap = new float[nWidth * 6 * nWidth];	}	~GBoxScene()	{		delete[] m_pDepthMap;	}	GImage* GetImage() { return &m_image; }	float* GetDepthMap() { return m_pDepthMap; }	void RayToPoint(float* pnOutX, float* pnOutY, GRayTraceVector* pRay)	{		int nFrame, u, v;		GRayTraceReal xx = pRay->m_vals[0] * pRay->m_vals[0];		GRayTraceReal yy = pRay->m_vals[1] * pRay->m_vals[1];		GRayTraceReal zz = pRay->m_vals[2] * pRay->m_vals[2];		if(xx >= yy && xx >= zz)		{			nFrame = 0;			u = 2;			v = 1;		}		else if(yy >= zz)		{			u = 2;			nFrame = 1;			v = 0;		}		else		{			u = 0;			v = 1;			nFrame = 2;		}		int halfWidth = m_image.GetWidth() / 2;		float t = (float)halfWidth / pRay->m_vals[nFrame];		*pnOutX = t * pRay->m_vals[u] + halfWidth;		*pnOutY = t * pRay->m_vals[v] + halfWidth;		if(pRay->m_vals[nFrame] < 0)			nFrame += 3;		(*pnOutY) += m_image.GetWidth() * nFrame;	}	// The ray this returns is NOT normalized	void PointToRay(GRayTraceVector* pRay, int x, int y)	{		int nFrame = y / m_image.GetWidth();		y = y % m_image.GetWidth();		if(nFrame >= 3)		{			nFrame -= 3;			pRay->m_vals[nFrame] = -1;			x = m_image.GetWidth() - x;			y = m_image.GetWidth() - y;		}		else			pRay->m_vals[nFrame] = 1;		int u = (nFrame == 2 ? 0 : 2);		int v = (nFrame == 1 ? 0 : 1);		pRay->m_vals[u] = (float)(x * 2) / m_image.GetWidth() - 1;		pRay->m_vals[v] = (float)(y * 2) / m_image.GetWidth() - 1;	}};#endif // __GSPHEREIMAGE_H__

⌨️ 快捷键说明

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