aboutsummaryrefslogtreecommitdiff
path: root/xp/cgxp/wglmath.js
blob: 1b9b9e3da0771a36451a9a75556badea38132f73 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//Copyright Chris Xiong 2018
//License: Expat (MIT)
var v3d=function(x,y,z)
{
	this.x=(x!==undefined)?x:0;
	this.y=(y!==undefined)?y:0;
	this.z=(z!==undefined)?z:0;
}
v3d.prototype.l=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);}
v3d.prototype.n=function(){var L=this.l();if(L==0)return new v3d();return new v3d(this.x/L,this.y/L,this.z/L);}
v3d.prototype.ms=function(s)
{
	return new v3d(this.x*s,this.y*s,this.z*s);
}
v3d.prototype.mm=function(m)
{
	return new v3d(
		m[0]*this.x+m[4]*this.y+m[8]*this.z,
		m[1]*this.x+m[5]*this.y+m[9]*this.z,
		m[2]*this.x+m[6]*this.y+m[10]*this.z
	);
}
v3d.prototype.add=function(b)
{
	return new v3d(this.x+b.x,this.y+b.y,this.z+b.z);
}
v3d.prototype.subtract=function(b)
{
	return new v3d(this.x-b.x,this.y-b.y,this.z-b.z);
}
v3d.prototype.dot=function(b)
{
	return this.x*b.x+this.y*b.y+this.z*b.z;
}
v3d.prototype.cross=function(b)
{
	return new v3d(
		this.y*b.z-this.z*b.y,
		this.z*b.x-this.x*b.z,
		this.x*b.y-this.y*b.x
	);
}
function buildIdentityMatrix()
{
	var m=new Float32Array(16);
	for(var i=0;i<4;++i)m[i*4+i]=1.;
	return m;
}
function buildProjectionMatrix2D(w,h)
{
	var m=buildIdentityMatrix();
	m[0]=2/w;m[5]=2/h;m[10]=-2;
	m[12]=m[13]=m[14]=-1;
	return m;
}
function buildProjectionMatrix3D(w,h,fov,near,far)
{
	var m=new Float32Array(16);
	var f=1./Math.tan(Math.PI*fov/360.);
	var ar=w/h;
	m[0]=f/ar;m[5]=f;m[10]=(far+near)/(near-far);
	m[11]=-1.;m[14]=(2*far*near)/(near-far);
	return m;
}
function buildTranslationMatrix(x,y,z)
{
	var m=buildIdentityMatrix();
	m[12]=x;m[13]=y;m[14]=z;
	return m;
}
function buildRotationMatrix(a,x,y,z)
{
	var m=buildIdentityMatrix();
	//check (x,y,z) here
	var c=Math.cos(a),s=Math.sin(a);
	m[0]=x*x*(1-c)+c;m[4]=x*y*(1-c)-z*s;m[8]=x*z*(1-c)+y*s;
	m[1]=y*x*(1-c)+z*s;m[5]=y*y*(1-c)+c;m[9]=y*z*(1-c)-x*s;
	m[2]=x*z*(1-c)-y*s;m[6]=y*z*(1-c)+x*s;m[10]=z*x*(1-c)+c;
	m[15]=1.;
	return m;
}
function buildLookAtMatrix(e,a,u)
{
	var f=new v3d(a[0]-e[0],a[1]-e[1],a[2]-e[2]).n();
	var up=new v3d(u[0],u[1],u[2]).n();
	var r=f.cross(up).n();var p=r.cross(f);
	var m=buildIdentityMatrix();
	m[0]=r.x;m[4]=r.y;m[8]=r.z;
	m[1]=p.x;m[5]=p.y;m[9]=p.z;
	m[2]=-f.x;m[6]=-f.y;m[10]=-f.z;
	m=multMatrix(m,buildTranslationMatrix(-e[0],-e[1],-e[2]));
	return m;
}
function multMatrix(a,b)
{
	var r=new Float32Array(16);
	for(var i=0;i<4;++i)
	for(var j=0;j<4;++j)
	for(var k=0;k<4;++k)
		r[i*4+j]+=a[i*4+k]*b[k*4+j];
	return r;
}