Skip to main content
gamedev.net
🔒 Locked

Point sprite problem

Started by Kackurot Aug 2, 2006 at 5:32 AM 2 replies 2.1k views
Original Post
Kackurot
Kackurot
hi, I have a problem with rendering opengl point sprites. when I render my sprites they look small when im close to them and grow large when I move away from them. Im doing my matrix calculations right with my camera and such. Maybe its the inverse translate thing with the camera? Or are they suppose to get small when I am close to them and get large when I move away from them? Can anyone help me with this?
[file:///C:/My%20Documents/kack.gif]
K_I_L_E_R
K_I_L_E_R
What set of equations are you using for your camera matrix?
What operations are you using that effects the camera?

You need to give more information because not all of us can read people's minds across the Internet.
Rasmadrak
Rasmadrak
It could be that they don't change size at all...

are you really sure that they are bigger further away, or do they just LOOK bigger (compared to other perspectified geometry) ?

"Game Maker For Life, probably never professional thou." =)
Kackurot
Kackurot
Particle emitter class stuff
typedef struct Particle_t{	vec3 position;	vec3 direction;	float energy;	float velocity;	vec4 color;}PARTICLE;struct EmitterInfo_t{	float TimeToEmitNewParticles;	float MaxParticleEnergy;	float EnergyDecrAmount;	unsigned int ParticlesEmitedAtOnce;	vec4	StartColor,EndColor;	float  MinSize,MaxSize;		//particle sizes	bool bGravity,bWind;		//enviroment effects	vec3 gravity_dir,wind_dir;	float gravity_scale,wind_scale;	float particle_vel;};class ParticleEmitter :	public RefCount{public:	ParticleEmitter(unsigned int nMaxParticles,unsigned int nTextureID);		void EmitParticles(float Time);	bool Emitting();	void Update();	void Render();	void StopRender(){ m_CurEmitted = 0; bEmit = false;}	EmitterInfo_t m_Info;	SPHERE m_ColSphere;	mat4 orientation;protected:	~ParticleEmitter(void);	void UpdateParticle(float fTime,		unsigned int nNumParticles,PARTICLE* pParticle);	virtual void SetUpParticles(unsigned int nNum,PARTICLE* pParticles);	virtual void AnimateParticle(float fTime,PARTICLE* pParticle);	const unsigned int m_MaxParticles;	unsigned int m_TextureID;	unsigned int m_CurEmitted;	float m_fMaxTime;	float m_fBaseTime;	float m_fEmitTime;	unsigned int m_nCurIndex;	PARTICLE* m_pParticles;	GlDataBuffer* m_pVertexData;		//VBO	bool bEmit;	Timer m_timer;};


The code for this class
float quadric[] = {0.0f,0.0f,1.0f};struct ParticleInfo{	vec3 pos;	vec4 color;};ParticleEmitter::ParticleEmitter(unsigned int nMaxParticles,unsigned int nTextureID):m_MaxParticles(nMaxParticles),m_TextureID(nTextureID),m_CurEmitted(0),m_nCurIndex(0),bEmit(1){	float mt[16];	int vw[4];	m_ColSphere.position = vec3(0,0,0);	m_ColSphere.radius = 1.0f;	m_pParticles = new PARTICLE[m_MaxParticles];	memset (m_pParticles,0,sizeof(PARTICLE)*m_MaxParticles);	m_pVertexData = new GlDataBuffer;	glGetFloatv (GL_PROJECTION_MATRIX,mt);	glGetIntegerv (GL_VIEWPORT,vw);	//sets up attenuation for sprite sizes	float h = vw[2];	float H = 2.0f/mt[0];	float D0 = sqrt(2.0f)*h/H;	float k = 1.0f/(1.0f + 2 * ((1/mt[0]) * (1/mt[0])));	quadric[2] = (((1/D0) * (1/D0)) * k);	m_timer.Start ();}ParticleEmitter::~ParticleEmitter(void){	delete [] m_pParticles;	m_pVertexData->unRef();}void ParticleEmitter::EmitParticles(float Time){	if( !m_pVertexData->Created () )	{		m_pVertexData->Create (GlDataBuffer::DB_DYNAMIC,			GlDataBuffer::DB_VERTICES,sizeof(ParticleInfo) * m_MaxParticles);	}	m_fBaseTime = m_timer.GetSeconds ();	m_fMaxTime = Time;	m_CurEmitted = m_MaxParticles;	srand((unsigned int)m_fBaseTime);			memset(m_pParticles,0, sizeof( PARTICLE )* m_MaxParticles );	bEmit = true;	}void ParticleEmitter::SetUpParticles(unsigned int nNum,PARTICLE* pParticles){		for( register int i = 0; i < nNum; ++i )	{		 pParticles[ i ].direction.x = (float)(rand() % 360);		 pParticles[ i ].direction.y = (float)(rand() % 360);		 pParticles[ i ].direction.z = (float)(rand() % 360);		 pParticles[ i ].energy = m_Info.MaxParticleEnergy;		 pParticles[ i ].color = m_Info.StartColor;		 pParticles[ i ].position = vec3(0,0,0);		 if((rand() % 2 + 1) == 2)			 pParticles[ i ].direction.x *= -1.0f;		 if((rand() % 3 + 1) == 1)			 pParticles[ i ].direction.y *= -1.0f;		 if((rand() % 4 + 1) == 3)			 pParticles[ i ].direction.z *= -1.0f;		 int r = rand()%4 + 1;		 pParticles[ i ].velocity = m_Info.particle_vel * r;		 pParticles[ i ].direction.normalize ();	}}void ParticleEmitter::AnimateParticle(float fTime,PARTICLE* pParticle){	float percent = pParticle->energy/m_Info.MaxParticleEnergy;	pParticle->color = m_Info.StartColor * ( percent ) + m_Info.EndColor * ( 1 - percent);	pParticle->color.w = 1.0f * percent;	pParticle->position += ( pParticle->direction * pParticle->velocity * percent);	if( m_Info.bGravity )		pParticle->position += m_Info.gravity_dir * m_Info.gravity_scale;	if( m_Info.bWind )		pParticle->position += m_Info.wind_dir * m_Info.wind_scale;	pParticle->energy += -m_Info.EnergyDecrAmount;}void ParticleEmitter::UpdateParticle(float fTime,					unsigned int nNumParticles,PARTICLE* pParticle){	vector< ParticleInfo > active_particles;	unsigned int nCurEmitted = 0;	// check to see if the emitter should die	if( m_fMaxTime != 0.0f )	{		if( (fTime - m_fBaseTime) > m_fMaxTime )		{			if(!m_CurEmitted)			{				return;			}else				bEmit = false;		}	}	// go through and update the particles	for( register int i = 0; i < nNumParticles; ++i )	{		if( pParticle[ i ].energy > 0.0f )		{			ParticleInfo info;			AnimateParticle (fTime,&pParticle[ i ]);						info.color = pParticle[ i ].color;			info.pos   = pParticle[ i ].position; 			active_particles.push_back ( info );			++nCurEmitted;		}	}	//check to see if we can still emit	if( bEmit )// see if its time to add new particles	if( (fTime - m_fEmitTime) > m_Info.TimeToEmitNewParticles )	{		m_fEmitTime = fTime;		int emit_count = 0;		for( register int i = 0; i < nNumParticles; ++i )		{			if( m_pParticles[ i ].energy <= 0.0f )			{				emit_count++;				SetUpParticles (1,&m_pParticles);			}			if( emit_count > m_Info.ParticlesEmitedAtOnce )				break;		}	}	//put the active particles in the vertex buffer for rendering	if( nCurEmitted )	{		ParticleInfo* p = (ParticleInfo*)m_pVertexData->Lock (GlDataBuffer::DB_WRITE);		for( size_t i = 0; i < active_particles.size() ; ++i )		{			p[ i ] = active_particles[ i ]; 		}		m_pVertexData->Unlock ();		if( !m_pVertexData->DataValid () )		{			ParticleInfo* p = (ParticleInfo*)m_pVertexData->Lock (GlDataBuffer::DB_WRITE);			for( size_t i = 0; i < active_particles.size() ; ++i )			{				p[ i ] = active_particles[ i ]; 			}			m_pVertexData->Unlock ();		}	}	m_CurEmitted = nCurEmitted;}void ParticleEmitter::Render(){	float mt[16];	int vw[4];	if( m_pVertexData->DataValid () && m_CurEmitted)	{								glPushClientAttrib (GL_ALL_ATTRIB_BITS);				glDepthMask (0);		glEnable(GL_POINT_SPRITE_ARB);		glEnable(GL_VERTEX_ARRAY);		glEnable(GL_COLOR_ARRAY);		m_pVertexData->Bind ();				glTexEnvi(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE_ARB,GL_TRUE);		glVertexPointer (3,GL_FLOAT,sizeof(ParticleInfo),0);		glColorPointer (4,GL_FLOAT,sizeof(ParticleInfo),(const GLvoid*)((char*)(sizeof(float)*3)));		TexRef tex = CTextureMgr::getMgr ().GetTexture(m_TextureID);						if(!tex.Null ())		{			tex->SetTextureUnit (0);			tex->EnableUnit (1);			tex->Bind ();		}		glPointSize (1.0f);				glPointParameterf ( GL_POINT_SIZE_MIN, m_Info.MinSize );		glPointParameterf ( GL_POINT_SIZE_MAX, m_Info.MaxSize );		glPointParameterf ( GL_POINT_FADE_THRESHOLD_SIZE, m_Info.MaxSize + 1);		glPointParameterfv ( GL_POINT_DISTANCE_ATTENUATION, quadric );		glEnable (GL_BLEND);		glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );		glDrawArrays (GL_POINTS,0,m_CurEmitted);		glDisable (GL_BLEND);		if(!tex.Null ())		{			tex->EnableUnit (0);			tex.Release ();		}						m_pVertexData->UnBind ();		glDisable (GL_COLOR_ARRAY);		glDisable (GL_VERTEX_ARRAY);		glDisable (GL_POINT_SPRITE_ARB);		glTexEnvi(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE_ARB,GL_FALSE);		glDepthMask (1);		glPopClientAttrib ();					}}void ParticleEmitter::Update(){	float t = m_timer.GetSeconds ();	UpdateParticle (t,m_MaxParticles,m_pParticles);}bool ParticleEmitter::Emitting(){	return bEmit;}


I use the inverse trans for my camera.
The GetInvsTrans does the calculation before passing to glMultMatrix

const vec3 gUp(0,1,0);CCamera::CCamera(void){	matrix[0] = 1;	matrix[4] = 0; matrix[8] = 0; matrix[12] = 0;	matrix[1] = 0; matrix[5] = 1; matrix[9] = 0; matrix[13] = 0;	matrix[2] = 0; matrix[6] = 0; matrix[10] = -1;matrix[14] = 0;}CCamera::~CCamera(void){}CCamera::CCamera(float Xx,float Xy,float Xz,		float Yx,float Yy,float Yz,		float Zx,float Zy,float Zz,		float x,float y,float z){	matrix[0] = Xx;	matrix[4] = Yx; matrix[8] = Zx; matrix[12] = x;	matrix[1] = Xy; matrix[5] = Yy; matrix[9] = Zy; matrix[13] = y;	matrix[2] = Xz; matrix[6] = Yz; matrix[10] = Zz;matrix[14] = z;}void CCamera::Set (float Xx,float Xy,float Xz, float Yx,float Yy,				   float Yz, float Zx,float Zy,float Zz, 				   float x,float y,float z){	matrix[0] = Xx;	matrix[4] = Yx; matrix[8] = Zx; matrix[12] = x;	matrix[1] = Xy; matrix[5] = Yy; matrix[9] = Zy; matrix[13] = y;	matrix[2] = Xz; matrix[6] = Yz; matrix[10] = Zz;matrix[14] = z;}void CCamera::Set(vec3& x,vec3& y,vec3& z){	Set(x.x,x.y,x.z,y.x,y.y,y.z,z.x,z.y,z.z,matrix[12],matrix[13],matrix[14]);}mat4 CCamera::GetInvsTrans(){	mat4 m;	UpdateCamera ();	memcpy (m.mat,matrix.mat,sizeof(float)*16);	m = m.inverse ();	m[12] = -(vec3(matrix[12],matrix[13],matrix[14]) * vec3(matrix[0],matrix[1],matrix[2]));	m[13] = -(vec3(matrix[12],matrix[13],matrix[14]) * vec3(matrix[4],matrix[5],matrix[6]));	m[14] = -(vec3(matrix[12],matrix[13],matrix[14]) * vec3(matrix[8],matrix[9],matrix[10]));	return m;}void CCamera::UpdateCamera(){	vec3 z(matrix[8],matrix[9],matrix[10]);	vec3 x,y;	z.normalize ();	x = cross(z,vec3(0,1,0));	x.normalize ();	y = cross(x,z);	y.normalize ();	Set(x,y,z);}mat4 CCamera::GetMatrix(){	mat4 m;	UpdateCamera ();	memcpy(m.mat,matrix.mat,sizeof(float) * 16 );	return m;}void CCamera::RotLocalX(float angle){	mat4 rot;	rot.rotate (matrix[0],matrix[1],matrix[2],angle);		//vec3 y,x;	//matrix = rot * matrix;	vec3 *z = matrix.getRowZ ();	*z = rot * (*z);	if( (*z) * gUp > 0.70f ||		(*z) * gUp < -0.70f)	{		rot.rotate (matrix[0],matrix[1],matrix[2],-angle);		*z = rot * (*z);	}}void CCamera::RotLocaly(float angle){	mat4 rot;	rot.rotate (matrix[4],matrix[5],matrix[6],angle);		//vec3 y,x;	vec3 *z = matrix.getRowZ ();	*z = rot * (*z);}void CCamera::RotLocalZ(float angle){	mat4 rot;	rot.rotate (matrix[8],matrix[9],matrix[10],angle);		//vec3 y,x;	vec3 *z = matrix.getRowZ ();	*z = rot * (*z);}void CCamera::RotGlobalX(float angle){	mat4 rot;	rot.rotate (1,0,0,angle);		//vec3 y,x;	vec3 *z = matrix.getRowZ ();		if((*z) * gUp > 0.70f ||		(*z) * gUp < -0.70f)	{		rot.rotate (1,0,0,-angle);		*z = rot * (*z);	}}void CCamera::RotGlobalY(float angle){	mat4 rot;	rot.rotate (0,1,0,angle);		//vec3 y,x;	vec3 *z = matrix.getRowZ ();	*z = rot * (*z);}void CCamera::RotGlobalZ(float angle){	mat4 rot;	rot.rotate (0,0,1,angle);		//vec3 y,x;	vec3 *z = matrix.getRowZ ();	*z = rot * (*z);}void CCamera::TranslateXYZ( float Xaxis,float Yaxis,float Zaxis ){	mat4 trans;	trans.translate( Xaxis, Yaxis, Zaxis );	matrix = matrix * trans;}void CCamera::ReCalcFrustum(mat4& projection){}


Im using the math code from the math lib from Frustum.org
heres the code if no one knows of this site
/* mathlib** Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifndef __MATHLIB_H__#define __MATHLIB_H__#include <math.h>#define EPSILON 1e-6f#define PI 3.14159265358979323846f#define DEG2RAD (PI / 180.0f)#define RAD2DEG (180.0f / PI)struct vec2;struct vec3;struct vec4;struct mat3;struct mat4;struct quat;/*****************************************************************************//*                                                                           *//* vec2                                                                      *//*                                                                           *//*****************************************************************************/struct vec2 {	inline vec2() : x(0), y(0) { }	inline vec2(float x,float y) : x(x), y(y) { }	inline vec2(const float *v) : x(v[0]), y(v[1]) { }	inline vec2(const vec2 &v) : x(v.x), y(v.y) { }	inline int operator==(const vec2 &v) { return (fabs(x - v.x) < EPSILON && fabs(y - v.y) < EPSILON); }	inline int operator!=(const vec2 &v) { return !(*this == v); }	inline const vec2 operator*(float f) const { return vec2(x * f,y * f); }	inline const vec2 operator/(float f) const { return vec2(x / f,y / f); }	inline const vec2 operator+(const vec2 &v) const { return vec2(x + v.x,y + v.y); }	inline const vec2 operator-() const { return vec2(-x,-y); }	inline const vec2 operator-(const vec2 &v) const { return vec2(x - v.x,y - v.y); }	inline vec2 &operator*=(float f) { return *this = *this * f; }	inline vec2 &operator/=(float f) { return *this = *this / f; }	inline vec2 &operator+=(const vec2 &v) { return *this = *this + v; }	inline vec2 &operator-=(const vec2 &v) { return *this = *this - v; }	inline float operator*(const vec2 &v) const { return x * v.x + y * v.y; }	inline bool ZeroCom()const{ return ( x == 0 || y == 0);}	inline operator float*() { return (float*)&x }	inline operator const float*() const { return (float*)&x }	inline float &operator[](int i) { return ((float*)&x); }	inline const float operator[](int i) const { return ((float*)&x); }	inline float length() const { return sqrt(x * x + y * y); }	inline float normalize() {		float inv,length = sqrt(x * x + y * y);		if(length < EPSILON) return 0.0;		inv = 1.0f / length;		x *= inv;		y *= inv;		return length;	}	union {		struct {			float x,y;		};		float v[2];	};};/*****************************************************************************//*                                                                           *//* vec3                                                                      *//*                                                                           *//*****************************************************************************/struct vec3 {	inline vec3() : x(0), y(0), z(0) { }	inline vec3(float x,float y,float z) : x(x), y(y), z(z) { }	inline vec3(const float *v) : x(v[0]), y(v[1]), z(v[2]) { }	inline vec3(const vec3 &v) : x(v.x), y(v.y), z(v.z) { }	inline vec3(const vec4 &v);	inline int operator==(const vec3 &v) { return (fabs(x - v.x) < EPSILON && fabs(y - v.y) < EPSILON && fabs(z - v.z) < EPSILON); }	inline int operator!=(const vec3 &v) { return !(*this == v); }	inline vec3& operator=(const float v) { x = v; y = v; z = v; return *this; }	inline const vec3 operator*(float f) const { return vec3(x * f,y * f,z * f); }	inline const vec3 operator/(float f) const { return vec3(x / f,y / f,z / f); }	inline const vec3 operator+(const vec3 &v) const { return vec3(x + v.x,y + v.y,z + v.z); }	inline const vec3 operator-() const { return vec3(-x,-y,-z); }	inline const vec3 operator-(const vec3 &v) const { return vec3(x - v.x,y - v.y,z - v.z); }	inline vec3 &operator*=(float f) { return *this = *this * f; }	inline vec3 &operator/=(float f) { return *this = *this / f; }	inline vec3 &operator+=(const vec3 &v) { return *this = *this + v; }	inline vec3 &operator-=(const vec3 &v) { return *this = *this - v; }	inline float operator*(const vec3 &v) const { return x * v.x + y * v.y + z * v.z; }	inline float operator*(const vec4 &v) const;	inline operator float*() { return (float*)&x }	inline operator const float*() const { return (float*)&x }	inline float &operator[](int i) { return ((float*)&x); }	inline const float operator[](int i) const { return ((float*)&x); }	inline float length() const { return sqrt(x * x + y * y + z * z); }	inline float normalize() {		float inv,length = sqrt(x * x + y * y + z * z);		if(length < EPSILON) return 0.0;		inv = 1.0f / length;		x *= inv;		y *= inv;		z *= inv;		return length;	}	inline void cross(const vec3 &v1,const vec3 &v2) {		x = v1.y * v2.z - v1.z * v2.y;		y = v1.z * v2.x - v1.x * v2.z;		z = v1.x * v2.y - v1.y * v2.x;	}	union {		struct {			float x,y,z;		};		float v[3];	};};inline vec3 cross(const vec3 &v1,const vec3 &v2) {	vec3 ret;	ret.x = v1.y * v2.z - v1.z * v2.y;	ret.y = v1.z * v2.x - v1.x * v2.z;	ret.z = v1.x * v2.y - v1.y * v2.x;	return ret;}inline float scalarTriple(const vec3& v1,const vec3& v2,const vec3& v3){	return cross(v2,v1) * v3;}/*****************************************************************************//*                                                                           *//* vec4                                                                      *//*                                                                           *//*****************************************************************************/struct vec4 {	inline vec4() : x(0), y(0), z(0), w(1) { }	inline vec4(float x,float y,float z,float w) : x(x), y(y), z(z), w(w) { }	inline vec4(const float *v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) { }	inline vec4(const vec3 &v) : x(v.x), y(v.y), z(v.z), w(1) { }	inline vec4(const vec3 &v,float w) : x(v.x), y(v.y), z(v.z), w(w) { }	inline vec4(const vec4 &v) : x(v.x), y(v.y), z(v.z), w(v.w) { }	inline int operator==(const vec4 &v) { return (fabs(x - v.x) < EPSILON && fabs(y - v.y) < EPSILON && fabs(z - v.z) < EPSILON && fabs(w - v.w) < EPSILON); }	inline int operator!=(const vec4 &v) { return !(*this == v); }	inline const vec4 operator*(float f) const { return vec4(x * f,y * f,z * f,w * f); }	inline const vec4 operator/(float f) const { return vec4(x / f,y / f,z / f,w / f); }	inline const vec4 operator+(const vec4 &v) const { return vec4(x + v.x,y + v.y,z + v.z,w + v.w); }	inline const vec4 operator-() const { return vec4(-x,-y,-z,-w); }	inline const vec4 operator-(const vec4 &v) const { return vec4(x - v.x,y - v.y,z - v.z,z - v.w); }	inline vec4 &operator*=(float f) { return *this = *this * f; }	inline vec4 &operator/=(float f) { return *this = *this / f; }	inline vec4 &operator+=(const vec4 &v) { return *this = *this + v; }	inline vec4 &operator-=(const vec4 &v) { return *this = *this - v; }	inline float operator*(const vec3 &v) const { return x * v.x + y * v.y + z * v.z + w; }	inline float operator*(const vec4 &v) const { return x * v.x + y * v.y + z * v.z + w * v.w; }	inline operator float*() { return (float*)&x }	inline operator const float*() const { return (float*)&x }	inline float &operator[](int i) { return ((float*)&x); }	inline const float operator[](int i) const { return ((float*)&x); }	inline float normalize() { float dist = sqrt( x * x + y * y + z * z + w * w );		float inv = 1/dist;		x *= inv;		y *= inv;		z *= inv;		w *= inv;		return dist;	}	union {		struct {			float x,y,z,w;		};		float v[4];	};};inline vec3::vec3(const vec4 &v) {	x = v.x;	y = v.y;	z = v.z;}inline float vec3::operator*(const vec4 &v) const {	return x * v.x + y * v.y + z * v.z + v.w;}/*****************************************************************************//*                                                                           *//* mat3                                                                      *//*                                                                           *//*****************************************************************************/struct mat3 {	mat3() {		mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0;		mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0;		mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0;	}	mat3(const float *m) {		mat[0] = m[0]; mat[3] = m[3]; mat[6] = m[6];		mat[1] = m[1]; mat[4] = m[4]; mat[7] = m[7];		mat[2] = m[2]; mat[5] = m[5]; mat[8] = m[8];	}	mat3(const mat3 &m) {		mat[0] = m[0]; mat[3] = m[3]; mat[6] = m[6];		mat[1] = m[1]; mat[4] = m[4]; mat[7] = m[7];		mat[2] = m[2]; mat[5] = m[5]; mat[8] = m[8];	}	mat3(const mat4 &m);	vec3 operator*(const vec3 &v) const {		vec3 ret;		ret[0] = mat[0] * v[0] + mat[3] * v[1] + mat[6] * v[2];		ret[1] = mat[1] * v[0] + mat[4] * v[1] + mat[7] * v[2];		ret[2] = mat[2] * v[0] + mat[5] * v[1] + mat[8] * v[2];		return ret;	}	vec4 operator*(const vec4 &v) const {		vec4 ret;		ret[0] = mat[0] * v[0] + mat[3] * v[1] + mat[6] * v[2];		ret[1] = mat[1] * v[0] + mat[4] * v[1] + mat[7] * v[2];		ret[2] = mat[2] * v[0] + mat[5] * v[1] + mat[8] * v[2];		ret[3] = v[3];		return ret;	}	mat3 operator*(float f) const {		mat3 ret;		ret[0] = mat[0] * f; ret[3] = mat[3] * f; ret[6] = mat[6] * f;		ret[1] = mat[1] * f; ret[4] = mat[4] * f; ret[7] = mat[7] * f;		ret[2] = mat[2] * f; ret[5] = mat[5] * f; ret[8] = mat[8] * f;		return ret;	}	mat3 operator*(const mat3 &m) const {		mat3 ret;		ret[0] = mat[0] * m[0] + mat[3] * m[1] + mat[6] * m[2];		ret[1] = mat[1] * m[0] + mat[4] * m[1] + mat[7] * m[2];		ret[2] = mat[2] * m[0] + mat[5] * m[1] + mat[8] * m[2];		ret[3] = mat[0] * m[3] + mat[3] * m[4] + mat[6] * m[5];		ret[4] = mat[1] * m[3] + mat[4] * m[4] + mat[7] * m[5];		ret[5] = mat[2] * m[3] + mat[5] * m[4] + mat[8] * m[5];		ret[6] = mat[0] * m[6] + mat[3] * m[7] + mat[6] * m[8];		ret[7] = mat[1] * m[6] + mat[4] * m[7] + mat[7] * m[8];		ret[8] = mat[2] * m[6] + mat[5] * m[7] + mat[8] * m[8];		return ret;	}	mat3 operator+(const mat3 &m) const {		mat3 ret;		ret[0] = mat[0] + m[0]; ret[3] = mat[3] + m[3]; ret[6] = mat[6] + m[6];		ret[1] = mat[1] + m[1]; ret[4] = mat[4] + m[4]; ret[7] = mat[7] + m[7];		ret[2] = mat[2] + m[2]; ret[5] = mat[5] + m[5]; ret[8] = mat[8] + m[8];		return ret;	}	mat3 operator-(const mat3 &m) const {		mat3 ret;		ret[0] = mat[0] - m[0]; ret[3] = mat[3] - m[3]; ret[6] = mat[6] - m[6];		ret[1] = mat[1] - m[1]; ret[4] = mat[4] - m[4]; ret[7] = mat[7] - m[7];		ret[2] = mat[2] - m[2]; ret[5] = mat[5] - m[5]; ret[8] = mat[8] - m[8];		return ret;	}	mat3 &operator*=(float f) { return *this = *this * f; }	mat3 &operator*=(const mat3 &m) { return *this = *this * m; }	mat3 &operator+=(const mat3 &m) { return *this = *this + m; }	mat3 &operator-=(const mat3 &m) { return *this = *this - m; }	operator float*() { return mat; }	operator const float*() const { return mat; }	float &operator[](int i) { return mat; }	const float operator[](int i) const { return mat; }	mat3 transpose() const {		mat3 ret;		ret[0] = mat[0]; ret[3] = mat[1]; ret[6] = mat[2];		ret[1] = mat[3]; ret[4] = mat[4]; ret[7] = mat[5];		ret[2] = mat[6]; ret[5] = mat[7]; ret[8] = mat[8];		return ret;	}	float det() const {		float det;		det = mat[0] * mat[4] * mat[8];		det += mat[3] * mat[7] * mat[2];		det += mat[6] * mat[1] * mat[5];		det -= mat[6] * mat[4] * mat[2];		det -= mat[3] * mat[1] * mat[8];		det -= mat[0] * mat[7] * mat[5];		return det;	}	mat3 inverse() const {		mat3 ret;		float idet = 1.0f / det();		ret[0] =  (mat[4] * mat[8] - mat[7] * mat[5]) * idet;		ret[1] = -(mat[1] * mat[8] - mat[7] * mat[2]) * idet;		ret[2] =  (mat[1] * mat[5] - mat[4] * mat[2]) * idet;		ret[3] = -(mat[3] * mat[8] - mat[6] * mat[5]) * idet;		ret[4] =  (mat[0] * mat[8] - mat[6] * mat[2]) * idet;		ret[5] = -(mat[0] * mat[5] - mat[3] * mat[2]) * idet;		ret[6] =  (mat[3] * mat[7] - mat[6] * mat[4]) * idet;		ret[7] = -(mat[0] * mat[7] - mat[6] * mat[1]) * idet;		ret[8] =  (mat[0] * mat[4] - mat[3] * mat[1]) * idet;		return ret;	}	void zero() {		mat[0] = 0.0; mat[3] = 0.0; mat[6] = 0.0;		mat[1] = 0.0; mat[4] = 0.0; mat[7] = 0.0;		mat[2] = 0.0; mat[5] = 0.0; mat[8] = 0.0;	}	void identity() {		mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0;		mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0;		mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0;	}	void rotate(const vec3 &axis,float angle) {		float rad = angle * DEG2RAD;		float c = cos(rad);		float s = sin(rad);		vec3 v = axis;		v.normalize();		float xx = v.x * v.x;		float yy = v.y * v.y;		float zz = v.z * v.z;		float xy = v.x * v.y;		float yz = v.y * v.z;		float zx = v.z * v.x;		float xs = v.x * s;		float ys = v.y * s;		float zs = v.z * s;		mat[0] = (1.0f - c) * xx + c; mat[3] = (1.0f - c) * xy - zs; mat[6] = (1.0f - c) * zx + ys;		mat[1] = (1.0f - c) * xy + zs; mat[4] = (1.0f - c) * yy + c; mat[7] = (1.0f - c) * yz - xs;		mat[2] = (1.0f - c) * zx - ys; mat[5] = (1.0f - c) * yz + xs; mat[8] = (1.0f - c) * zz + c;	}	void rotate(float x,float y,float z,float angle) {		rotate(vec3(x,y,z),angle);	}	void rotate_x(float angle) {		float rad = angle * DEG2RAD;		float c = cos(rad);		float s = sin(rad);		mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0;		mat[1] = 0.0; mat[4] = c; mat[7] = -s;		mat[2] = 0.0; mat[5] = s; mat[8] = c;	}	void rotate_y(float angle) {		float rad = angle * DEG2RAD;		float c = cos(rad);		float s = sin(rad);		mat[0] = c; mat[3] = 0.0; mat[6] = s;		mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0;		mat[2] = -s; mat[5] = 0.0; mat[8] = c;	}	void rotate_z(float angle) {		float rad = angle * DEG2RAD;		float c = cos(rad);		float s = sin(rad);		mat[0] = c; mat[3] = -s; mat[6] = 0.0;		mat[1] = s; mat[4] = c; mat[7] = 0.0;		mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0;	}	void scale(const vec3 &v) {		mat[0] = v.x; mat[3] = 0.0; mat[6] = 0.0;		mat[1] = 0.0; mat[4] = v.y; mat[7] = 0.0;		mat[2] = 0.0; mat[5] = 0.0; mat[8] = v.z;	}	void scale(float x,float y,float z) {		scale(vec3(x,y,z));	}	void orthonormalize() {		vec3 x(mat[0],mat[1],mat[2]);		vec3 y(mat[3],mat[4],mat[5]);		vec3 z;		x.normalize();		z.cross(x,y);		z.normalize();		y.cross(z,x);		y.normalize();		mat[0] = x.x; mat[3] = y.x; mat[6] = z.x;		mat[1] = x.y; mat[4] = y.y; mat[7] = z.y;		mat[2] = x.z; mat[5] = y.z; mat[8] = z.z;	}	float mat[9];};/*****************************************************************************//*                                                                           *//* mat4                                                                      *//*                                                                           *//*****************************************************************************/struct mat4 {	mat4() {		mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;		mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0;		mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	mat4(const vec3 &v) {		translate(v);	}	mat4(float x,float y,float z) {		translate(x,y,z);	}	mat4(const vec3 &axis,float angle) {		rotate(axis,angle);	}	mat4(float x,float y,float z,float angle) {		rotate(x,y,z,angle);	}	mat4(const mat3 &m) {		mat[0] = m[0]; mat[4] = m[3]; mat[8] = m[6]; mat[12] = 0.0;		mat[1] = m[1]; mat[5] = m[4]; mat[9] = m[7]; mat[13] = 0.0;		mat[2] = m[2]; mat[6] = m[5]; mat[10] = m[8]; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	mat4(const float *m) {		mat[0] = m[0]; mat[4] = m[4]; mat[8] = m[8]; mat[12] = m[12];		mat[1] = m[1]; mat[5] = m[5]; mat[9] = m[9]; mat[13] = m[13];		mat[2] = m[2]; mat[6] = m[6]; mat[10] = m[10]; mat[14] = m[14];		mat[3] = m[3]; mat[7] = m[7]; mat[11] = m[11]; mat[15] = m[15];	}	mat4(const mat4 &m) {		mat[0] = m[0]; mat[4] = m[4]; mat[8] = m[8]; mat[12] = m[12];		mat[1] = m[1]; mat[5] = m[5]; mat[9] = m[9]; mat[13] = m[13];		mat[2] = m[2]; mat[6] = m[6]; mat[10] = m[10]; mat[14] = m[14];		mat[3] = m[3]; mat[7] = m[7]; mat[11] = m[11]; mat[15] = m[15];	}	vec3 operator*(const vec3 &v) const {		vec3 ret;		ret[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12];		ret[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13];		ret[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14];		return ret;	}	vec4 operator*(const vec4 &v) const {		vec4 ret;		ret[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12] * v[3];		ret[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13] * v[3];		ret[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14] * v[3];		ret[3] = mat[3] * v[0] + mat[7] * v[1] + mat[11] * v[2] + mat[15] * v[3];		return ret;	}	mat4 operator*(float f) const {		mat4 ret;		ret[0] = mat[0] * f; ret[4] = mat[4] * f; ret[8] = mat[8] * f; ret[12] = mat[12] * f;		ret[1] = mat[1] * f; ret[5] = mat[5] * f; ret[9] = mat[9] * f; ret[13] = mat[13] * f;		ret[2] = mat[2] * f; ret[6] = mat[6] * f; ret[10] = mat[10] * f; ret[14] = mat[14] * f;		ret[3] = mat[3] * f; ret[7] = mat[7] * f; ret[11] = mat[11] * f; ret[15] = mat[15] * f;		return ret;	}	mat4 operator*(const mat4 &m) const {		mat4 ret;		ret[0] = mat[0] * m[0] + mat[4] * m[1] + mat[8] * m[2] + mat[12] * m[3];		ret[1] = mat[1] * m[0] + mat[5] * m[1] + mat[9] * m[2] + mat[13] * m[3];		ret[2] = mat[2] * m[0] + mat[6] * m[1] + mat[10] * m[2] + mat[14] * m[3];		ret[3] = mat[3] * m[0] + mat[7] * m[1] + mat[11] * m[2] + mat[15] * m[3];		ret[4] = mat[0] * m[4] + mat[4] * m[5] + mat[8] * m[6] + mat[12] * m[7];		ret[5] = mat[1] * m[4] + mat[5] * m[5] + mat[9] * m[6] + mat[13] * m[7];		ret[6] = mat[2] * m[4] + mat[6] * m[5] + mat[10] * m[6] + mat[14] * m[7];		ret[7] = mat[3] * m[4] + mat[7] * m[5] + mat[11] * m[6] + mat[15] * m[7];		ret[8] = mat[0] * m[8] + mat[4] * m[9] + mat[8] * m[10] + mat[12] * m[11];		ret[9] = mat[1] * m[8] + mat[5] * m[9] + mat[9] * m[10] + mat[13] * m[11];		ret[10] = mat[2] * m[8] + mat[6] * m[9] + mat[10] * m[10] + mat[14] * m[11];		ret[11] = mat[3] * m[8] + mat[7] * m[9] + mat[11] * m[10] + mat[15] * m[11];		ret[12] = mat[0] * m[12] + mat[4] * m[13] + mat[8] * m[14] + mat[12] * m[15];		ret[13] = mat[1] * m[12] + mat[5] * m[13] + mat[9] * m[14] + mat[13] * m[15];		ret[14] = mat[2] * m[12] + mat[6] * m[13] + mat[10] * m[14] + mat[14] * m[15];		ret[15] = mat[3] * m[12] + mat[7] * m[13] + mat[11] * m[14] + mat[15] * m[15];		return ret;	}	mat4 operator+(const mat4 &m) const {		mat4 ret;		ret[0] = mat[0] + m[0]; ret[4] = mat[4] + m[4]; ret[8] = mat[8] + m[8]; ret[12] = mat[12] + m[12];		ret[1] = mat[1] + m[1]; ret[5] = mat[5] + m[5]; ret[9] = mat[9] + m[9]; ret[13] = mat[13] + m[13];		ret[2] = mat[2] + m[2]; ret[6] = mat[6] + m[6]; ret[10] = mat[10] + m[10]; ret[14] = mat[14] + m[14];		ret[3] = mat[3] + m[3]; ret[7] = mat[7] + m[7]; ret[11] = mat[11] + m[11]; ret[15] = mat[15] + m[15];		return ret;	}	mat4 operator-(const mat4 &m) const {		mat4 ret;		ret[0] = mat[0] - m[0]; ret[4] = mat[4] - m[4]; ret[8] = mat[8] - m[8]; ret[12] = mat[12] - m[12];		ret[1] = mat[1] - m[1]; ret[5] = mat[5] - m[5]; ret[9] = mat[9] - m[9]; ret[13] = mat[13] - m[13];		ret[2] = mat[2] - m[2]; ret[6] = mat[6] - m[6]; ret[10] = mat[10] - m[10]; ret[14] = mat[14] - m[14];		ret[3] = mat[3] - m[3]; ret[7] = mat[7] - m[7]; ret[11] = mat[11] - m[11]; ret[15] = mat[15] - m[15];		return ret;	}	mat4 &operator*=(float f) { return *this = *this * f; }	mat4 &operator*=(const mat4 &m) { return *this = *this * m; }	mat4 &operator+=(const mat4 &m) { return *this = *this + m; }	mat4 &operator-=(const mat4 &m) { return *this = *this - m; }	operator float*() { return mat; }	operator const float*() const { return mat; }	float &operator[](int i) { return mat; }	const float operator[](int i) const { return mat; }	mat4 rotation() const {		mat4 ret;		ret[0] = mat[0]; ret[4] = mat[4]; ret[8] = mat[8]; ret[12] = 0;		ret[1] = mat[1]; ret[5] = mat[5]; ret[9] = mat[9]; ret[13] = 0;		ret[2] = mat[2]; ret[6] = mat[6]; ret[10] = mat[10]; ret[14] = 0;		ret[3] = 0; ret[7] = 0; ret[11] = 0; ret[15] = 1;		return ret;	}	mat4 transpose() const {		mat4 ret;		ret[0] = mat[0]; ret[4] = mat[1]; ret[8] = mat[2]; ret[12] = mat[3];		ret[1] = mat[4]; ret[5] = mat[5]; ret[9] = mat[6]; ret[13] = mat[7];		ret[2] = mat[8]; ret[6] = mat[9]; ret[10] = mat[10]; ret[14] = mat[11];		ret[3] = mat[12]; ret[7] = mat[13]; ret[11] = mat[14]; ret[15] = mat[15];		return ret;	}	mat4 transpose_rotation() const {		mat4 ret;		ret[0] = mat[0]; ret[4] = mat[1]; ret[8] = mat[2]; ret[12] = mat[12];		ret[1] = mat[4]; ret[5] = mat[5]; ret[9] = mat[6]; ret[13] = mat[13];		ret[2] = mat[8]; ret[6] = mat[9]; ret[10] = mat[10]; ret[14] = mat[14];		ret[3] = mat[3]; ret[7] = mat[7]; ret[14] = mat[14]; ret[15] = mat[15];		return ret;	}	float det() const {		float det;		det = mat[0] * mat[5] * mat[10];		det += mat[4] * mat[9] * mat[2];		det += mat[8] * mat[1] * mat[6];		det -= mat[8] * mat[5] * mat[2];		det -= mat[4] * mat[1] * mat[10];		det -= mat[0] * mat[9] * mat[6];		return det;	}	mat4 inverse() const {		mat4 ret;		float idet = 1.0f / det();		ret[0] =  (mat[5] * mat[10] - mat[9] * mat[6]) * idet;		ret[1] = -(mat[1] * mat[10] - mat[9] * mat[2]) * idet;		ret[2] =  (mat[1] * mat[6] - mat[5] * mat[2]) * idet;		ret[3] = 0.0;		ret[4] = -(mat[4] * mat[10] - mat[8] * mat[6]) * idet;		ret[5] =  (mat[0] * mat[10] - mat[8] * mat[2]) * idet;		ret[6] = -(mat[0] * mat[6] - mat[4] * mat[2]) * idet;		ret[7] = 0.0;		ret[8] =  (mat[4] * mat[9] - mat[8] * mat[5]) * idet;		ret[9] = -(mat[0] * mat[9] - mat[8] * mat[1]) * idet;		ret[10] =  (mat[0] * mat[5] - mat[4] * mat[1]) * idet;		ret[11] = 0.0;		ret[12] = -(mat[12] * ret[0] + mat[13] * ret[4] + mat[14] * ret[8]);		ret[13] = -(mat[12] * ret[1] + mat[13] * ret[5] + mat[14] * ret[9]);		ret[14] = -(mat[12] * ret[2] + mat[13] * ret[6] + mat[14] * ret[10]);		ret[15] = 1.0;		return ret;	}	void zero() {		mat[0] = 0.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;		mat[1] = 0.0; mat[5] = 0.0; mat[9] = 0.0; mat[13] = 0.0;		mat[2] = 0.0; mat[6] = 0.0; mat[10] = 0.0; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 0.0;	}	void identity() {		mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;		mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0;		mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	void rotate(const vec3 &axis,float angle) {		float rad = angle * DEG2RAD;		float c = cos(rad);		float s = sin(rad);		vec3 v = axis;		v.normalize();		float xx = v.x * v.x;		float yy = v.y * v.y;		float zz = v.z * v.z;		float xy = v.x * v.y;		float yz = v.y * v.z;		float zx = v.z * v.x;		float xs = v.x * s;		float ys = v.y * s;		float zs = v.z * s;		mat[0] = (1.0f - c) * xx + c; mat[4] = (1.0f - c) * xy - zs; mat[8] = (1.0f - c) * zx + ys; mat[12] = 0.0;		mat[1] = (1.0f - c) * xy + zs; mat[5] = (1.0f - c) * yy + c; mat[9] = (1.0f - c) * yz - xs; mat[13] = 0.0;		mat[2] = (1.0f - c) * zx - ys; mat[6] = (1.0f - c) * yz + xs; mat[10] = (1.0f - c) * zz + c; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	void rotate(float x,float y,float z,float angle) {		rotate(vec3(x,y,z),angle);	}	void rotate_x(float angle) {		float rad = angle * DEG2RAD;		float c = cos(rad);		float s = sin(rad);		mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;		mat[1] = 0.0; mat[5] = c; mat[9] = -s; mat[13] = 0.0;		mat[2] = 0.0; mat[6] = s; mat[10] = c; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	void rotate_y(float angle) {		float rad = angle * DEG2RAD;		float c = cos(rad);		float s = sin(rad);		mat[0] = c; mat[4] = 0.0; mat[8] = s; mat[12] = 0.0;		mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0;		mat[2] = -s; mat[6] = 0.0; mat[10] = c; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	void rotate_z(float angle) {		float rad = angle * DEG2RAD;		float c = cos(rad);		float s = sin(rad);		mat[0] = c; mat[4] = -s; mat[8] = 0.0; mat[12] = 0.0;		mat[1] = s; mat[5] = c; mat[9] = 0.0; mat[13] = 0.0;		mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	void scale(const vec3 &v) {		mat[0] = v.x; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;		mat[1] = 0.0; mat[5] = v.y; mat[9] = 0.0; mat[13] = 0.0;		mat[2] = 0.0; mat[6] = 0.0; mat[10] = v.z; mat[14] = 0.0;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	void scale(float x,float y,float z) {		scale(vec3(x,y,z));	}	void translate(const vec3 &v) {		mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = v.x;		mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = v.y;		mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = v.z;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	void translate(float x,float y,float z) {		translate(vec3(x,y,z));	}	void reflect(const vec4 &plane) {		float x = plane.x;		float y = plane.y;		float z = plane.z;		float x2 = x * 2.0f;		float y2 = y * 2.0f;		float z2 = z * 2.0f;		mat[0] = 1.0f - x * x2; mat[4] = -y * x2; mat[8] = -z * x2; mat[12] = -plane.w * x2;		mat[1] = -x * y2; mat[5] = 1.0f - y * y2; mat[9] = -z * y2; mat[13] = -plane.w * y2;		mat[2] = -x * z2; mat[6] = -y * z2; mat[10] = 1.0f - z * z2; mat[14] = -plane.w * z2;		mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;	}	void reflect(float x,float y,float z,float w) {		reflect(vec4(x,y,z,w));	}	void perspective(float fov,float aspect,float znear,float zfar) {		float y = tan(fov * PI / 360.0f);		float x = y * aspect;		mat[0] = 1.0f / x; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;		mat[1] = 0.0; mat[5] = 1.0f / y; mat[9] = 0.0; mat[13] = 0.0;		mat[2] = 0.0; mat[6] = 0.0; mat[10] = -(zfar + znear) / (zfar - znear); mat[14] = -(2.0f * zfar * znear) / (zfar - znear);		mat[3] = 0.0; mat[7] = 0.0; mat[11] = -1.0; mat[15] = 0.0;	}	void look_at(const vec3 &eye,const vec3 &dir,const vec3 &up) {		vec3 x,y,z;		mat4 m0,m1;		z = eye - dir;		z.normalize();		x.cross(up,z);		x.normalize();		y.cross(z,x);		y.normalize();		m0[0] = x.x; m0[4] = x.y; m0[8] = x.z; m0[12] = 0.0;		m0[1] = y.x; m0[5] = y.y; m0[9] = y.z; m0[13] = 0.0;		m0[2] = z.x; m0[6] = z.y; m0[10] = z.z; m0[14] = 0.0;		m0[3] = 0.0; m0[7] = 0.0; m0[11] = 0.0; m0[15] = 1.0;		m1.translate(-eye);		*this = m0 * m1;	}	void look_at(const float *eye,const float *dir,const float *up) {		look_at(vec3(eye),vec3(dir),vec3(up));	}	vec3* getRowX(){ return (vec3*)&mat[0];}	vec3* getRowY(){ return (vec3*)&mat[4];}	vec3* getRowZ(){ return (vec3*)&mat[8];}	vec3* getRowT(){ return (vec3*)&mat[12];}		float mat[16];};inline mat3::mat3(const mat4 &m) {	mat[0] = m[0]; mat[3] = m[4]; mat[6] = m[8];	mat[1] = m[1]; mat[4] = m[5]; mat[7] = m[9];	mat[2] = m[2]; mat[5] = m[6]; mat[8] = m[10];}/*****************************************************************************//*                                                                           *//* quat                                                                      *//*                                                                           *//*****************************************************************************/struct quat {	quat() : x(0), y(0), z(0), w(1) { }	quat(const vec3 &dir,float angle) {		set(dir,angle);	}	quat(float x,float y,float z,float angle) {		set(x,y,z,angle);	}	quat(const mat3 &m) {		float trace = m[0] + m[4] + m[8];		if(trace > 0.0) {			float s = sqrt(trace + 1.0f);			q[3] = 0.5f * s;			s = 0.5f / s;			q[0] = (m[5] - m[7]) * s;			q[1] = (m[6] - m[2]) * s;			q[2] = (m[1] - m[3]) * s;		} else {			static int next[3] = { 1, 2, 0 };			int i = 0;			if(m[4] > m[0]) i = 1;			if(m[8] > m[3 * i + i]) i = 2;			int j = next;			int k = next[j];			float s = sqrt(m[3 * i + i] - m[3 * j + j] - m[3 * k + k] + 1.0f);			q = 0.5f * s;			if(s != 0) s = 0.5f / s;			q[3] = (m[3 * j + k] - m[3 * k + j]) * s;			q[j] = (m[3 * i + j] + m[3 * j + i]) * s;			q[k] = (m[3 * i + k] + m[3 * k + i]) * s;		}	}	operator float*() { return (float*)&x }	operator const float*() const { return (float*)&x }	float &operator[](int i) { return ((float*)&x); }	const float operator[](int i) const { return ((float*)&x); }	quat operator*(const quat &q) const {		quat ret;		ret.x = w * q.x + x * q.x + y * q.z - z * q.y;		ret.y = w * q.y + y * q.w + z * q.x - x * q.z;		ret.z = w * q.z + z * q.w + x * q.y - y * q.x;		ret.w = w * q.w - x * q.x - y * q.y - z * q.z;		return ret;	}	void set(const vec3 &dir,float angle) {		float length = dir.length();		if(length != 0.0) {			length = 1.0f / length;			float sinangle = sin(angle * DEG2RAD / 2.0f);			x = dir[0] * length * sinangle;			y = dir[1] * length * sinangle;			z = dir[2] * length * sinangle;			w = cos(angle * DEG2RAD / 2.0f);		} else {			x = y = z = 0.0;			w = 1.0;		}	}	void set(float x,float y,float z,float angle) {		set(vec3(x,y,z),angle);	}	void slerp(const quat &q0,const quat &q1,float t) {		float k0,k1,cosomega = q0.x * q1.x + q0.y * q1.y + q0.z * q1.z + q0.w * q1.w;		quat q;		if(cosomega < 0.0) {			cosomega = -cosomega;			q.x = -q1.x;			q.y = -q1.y;			q.z = -q1.z;			q.w = -q1.w;		} else {			q.x = q1.x;			q.y = q1.y;			q.z = q1.z;			q.w = q1.w;		}		if(1.0 - cosomega > 1e-6) {			float omega = acos(cosomega);			float sinomega = sin(omega);			k0 = sin((1.0f - t) * omega) / sinomega;			k1 = sin(t * omega) / sinomega;		} else {			k0 = 1.0f - t;			k1 = t;		}		x = q0.x * k0 + q.x * k1;		y = q0.y * k0 + q.y * k1;		z = q0.z * k0 + q.z * k1;		w = q0.w * k0 + q.w * k1;	}	mat3 to_matrix() const {		mat3 ret;		float x2 = x + x;		float y2 = y + y;		float z2 = z + z;		float xx = x * x2;		float yy = y * y2;		float zz = z * z2;		float xy = x * y2;		float yz = y * z2;		float xz = z * x2;		float wx = w * x2;		float wy = w * y2;		float wz = w * z2;		ret[0] = 1.0f - (yy + zz); ret[3] = xy - wz; ret[6] = xz + wy;		ret[1] = xy + wz; ret[4] = 1.0f - (xx + zz); ret[7] = yz - wx;		ret[2] = xz - wy; ret[5] = yz + wx; ret[8] = 1.0f - (xx + yy);		return ret;	}	union {		struct {			float x,y,z,w;		};		float q[4];	};};#endif /* __MATHLIB_H__ */


Ok I procees the sprites, do the matrix calculation with my
camera ,save the gl matrix with push and pass my camera matrix
to gl and render my particles.

And of coures my point sprites get big moving away and get small up close
Everything elese works fine, objects are correct, the camera rotates fine, and my scene graph and quadtree are superb :). Damn point sprites not working right :(.
Please help

[Edited by - Kackurot on August 2, 2006 8:05:05 PM]
[file:///C:/My%20Documents/kack.gif]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.