window.P3D = {
texture:null,
g:null
};
P3D.clear =function(f, w, h) {
varg =this.g;
g.beginPath();
g.fillStyle = f;
g.fillRect(0, 0, w, h);
}
P3D.num_cmp =function(a,b){returna-b;}
P3D.drawTriangle =function(poss, uvs, shade_clr) {
varw =this.texture.width;
varh =this.texture.height;
varg =this.g;
varvAd = [ poss[1].x - poss[0].x , poss[1].y - poss[0].y ];
varvBd = [ poss[2].x - poss[0].x , poss[2].y - poss[0].y ];
varvA = [ uvs[1].u - uvs[0].u , uvs[1].v - uvs[0].v ];
varvB = [ uvs[2].u - uvs[0].u , uvs[2].v - uvs[0].v ];
vA[0] *= w;
vA[1] *= h;
vB[0] *= w;
vB[1] *= h;
varm =newM22();
m._11 = vA[0];
m._12 = vA[1];
m._21 = vB[0];
m._22 = vB[1];
varim = m.getInvert();
if(!im)returnfalse;
vara = im._11 * vAd[0] + im._12 * vBd[0];
varb = im._21 * vAd[0] + im._22 * vBd[0];
varc = im._11 * vAd[1] + im._12 * vBd[1];
vard = im._21 * vAd[1] + im._22 * vBd[1];
varwu = uvs[0].u * w;
varhv = uvs[0].v * h;
vardu = wu * a + hv * b;
vardv = wu * c + hv * d;
g.save();
g.beginPath();
g.moveTo(poss[0].x, poss[0].y);
g.lineTo(poss[1].x, poss[1].y);
g.lineTo(poss[2].x, poss[2].y);
g.clip();
g.transform(a, c, b, d, poss[0].x - du, poss[0].y - dv);
// bounds
varbx = [wu, wu+vA[0], wu+vB[0]];
varby = [hv, hv+vA[1], hv+vB[1]];
bx.sort(P3D.num_cmp);
by.sort(P3D.num_cmp);
varbw = bx[2] - bx[0];
varbh = by[2] - by[0];
if((bx[0]+bw) <= (w-1)) bw++;
if((by[0]+bh) <= (h-1)) bh++;
if(bx[0] >= 1) {bx[0]--; bw++;}
if(by[0] >= 1) {by[0]--; bh++;}
g.drawImage(this.texture, bx[0], by[0], bw, bh, bx[0], by[0], bw, bh);
if(shade_clr) {
g.fillStyle = shade_clr;
g.fillRect(bx[0], by[0], bw, bh);
}
g.restore();
returntrue;
}
P3D.drawTestByIndexBuffer =function(pos_buf, ix_buf, culling) {
varg =this.g;
if((ix_buf.length%3) != 0)
throw"invalid index buffer length!";
varlen = ix_buf.length/3;
vari, ibase, vbase;
varposs = [{},{},{}];
g.strokeWidth = 1;
for(i = 0, ibase = 0;i < len;++i)
{
vbase = ix_buf[ibase++] << 2;
poss[0].x = pos_buf[vbase++];
poss[0].y = pos_buf[vbase ];
vbase = ix_buf[ibase++] << 2;
poss[1].x = pos_buf[vbase++];
poss[1].y = pos_buf[vbase ];
vbase = ix_buf[ibase++] << 2;
poss[2].x = pos_buf[vbase++];
poss[2].y = pos_buf[vbase ];
// z component of cross product < 0 ?
varAx = poss[1].x - poss[0].x;
varAy = poss[1].y - poss[0].y;
varCx = poss[2].x - poss[1].x;
varCy = poss[2].y - poss[1].y;
varcull = ( (((Ax * Cy) - (Ay * Cx))*culling) < 0);
g.beginPath();
g.strokeStyle = cull ?"#592":"#0f0";
g.moveTo(poss[0].x, poss[0].y);
g.lineTo(poss[1].x, poss[1].y);
g.lineTo(poss[2].x, poss[2].y);
g.lineTo(poss[0].x, poss[0].y);
g.stroke();
}
}
P3D.drawByIndexBuffer =function(pos_buf, ix_buf, tx_buf, culling, z_clip) {
varw, h;
varcolor_polygon = !this.texture;
if(this.texture) {
w =this.texture.width;
h =this.texture.height;
}
varg =this.g;
varm =newM22();
if(!culling) culling = 0;
if((ix_buf.length%3) != 0)
throw"invalid index buffer length!";
vari, ibase, vbase, tbase, poss = [{},{},{}];
varlen = ix_buf.length/3;
varuv_0u, uv_0v, uv_1u, uv_1v, uv_2u, uv_2v;
for(i = 0, ibase = 0;i < len;++i)
{
tbase = ix_buf[ibase++] << 1
vbase = tbase << 1;
poss[0].x = pos_buf[vbase++]; uv_0u = tx_buf[tbase++];
poss[0].y = pos_buf[vbase++]; uv_0v = tx_buf[tbase];
if(z_clip && (pos_buf[vbase] < 0 || pos_buf[vbase] > 1)) {ibase += 2;continue;}
tbase = ix_buf[ibase++] << 1
vbase = tbase << 1;
poss[1].x = pos_buf[vbase++]; uv_1u = tx_buf[tbase++];
poss[1].y = pos_buf[vbase++]; uv_1v = tx_buf[tbase];
if(z_clip && (pos_buf[vbase] < 0 || pos_buf[vbase] > 1)) {++ibase;continue;}
tbase = ix_buf[ibase++] << 1
vbase = tbase << 1;
poss[2].x = pos_buf[vbase++]; uv_2u = tx_buf[tbase++];
poss[2].y = pos_buf[vbase++]; uv_2v = tx_buf[tbase];
if(z_clip && (pos_buf[vbase] < 0 || pos_buf[vbase] > 1)) {continue;}
varvAd = [ poss[1].x - poss[0].x , poss[1].y - poss[0].y ];
varvBd = [ poss[2].x - poss[0].x , poss[2].y - poss[0].y ];
varvCd = [ poss[2].x - poss[1].x , poss[2].y - poss[1].y ];
// z component of cross product < 0 ?
if( (((vAd[0] * vCd[1]) - (vAd[1] * vCd[0]))*culling) < 0)
continue;
if(color_polygon) {
g.fillStyle = uv_0u;
g.beginPath();
g.moveTo(poss[0].x, poss[0].y);
g.lineTo(poss[1].x, poss[1].y);
g.lineTo(poss[2].x, poss[2].y);
g.fill();
continue;
}
varvA = [ uv_1u - uv_0u , uv_1v - uv_0v ];
varvB = [ uv_2u - uv_0u , uv_2v - uv_0v ];
vA[0] *= w;
vA[1] *= h;
vB[0] *= w;
vB[1] *= h;
m._11 = vA[0];
m._12 = vA[1];
m._21 = vB[0];
m._22 = vB[1];
varim = m.getInvert();
if(!im) {continue;}
vara = im._11 * vAd[0] + im._12 * vBd[0];
varb = im._21 * vAd[0] + im._22 * vBd[0];
varc = im._11 * vAd[1] + im._12 * vBd[1];
vard = im._21 * vAd[1] + im._22 * vBd[1];
varwu = uv_0u * w;
varhv = uv_0v * h;
vardu = wu * a + hv * b;
vardv = wu * c + hv * d;
g.save();
g.beginPath();
g.moveTo(poss[0].x, poss[0].y);
g.lineTo(poss[1].x, poss[1].y);
g.lineTo(poss[2].x, poss[2].y);
g.clip();
g.transform(a, c, b, d, poss[0].x - du, poss[0].y - dv);
// bounds
varbx = [wu, wu+vA[0], wu+vB[0]];
varby = [hv, hv+vA[1], hv+vB[1]];
bx.sort(P3D.num_cmp);
by.sort(P3D.num_cmp);
varbw = bx[2] - bx[0];
varbh = by[2] - by[0];
if((bx[0]+bw) <= (w-1)) bw++;
if((by[0]+bh) <= (h-1)) bh++;
if(bx[0] >= 1) {bx[0]--; bw++;}
if(by[0] >= 1) {by[0]--; bh++;}
g.drawImage(this.texture, bx[0], by[0], bw, bh, bx[0], by[0], bw, bh);
/*
if (shade_clr) {
g.fillStyle = shade_clr;
g.fillRect(bx[0], by[0], bw, bh);
}
*/
g.restore();
}
}
functionVec3(_x, _y, _z)
{
this.x = _x || 0;
this.y = _y || 0;
this.z = _z || 0;
}
Vec3.prototype = {
zero:function() {
this.x =this.y =this.z = 0;
},
sub:function(v) {
this.x -= v.x;
this.y -= v.y;
this.z -= v.z;
returnthis;
},
add:function(v) {
this.x += v.x;
this.y += v.y;
this.z += v.z;
returnthis;
},
copyFrom:function(v) {
this.x = v.x;
this.y = v.y;
this.z = v.z;
returnthis;
},
norm:function() {
returnMath.sqrt(this.x*this.x +this.y*this.y +this.z*this.z);
},
normalize:function() {
varnrm = Math.sqrt(this.x*this.x +this.y*this.y +this.z*this.z);
if(nrm != 0)
{
this.x /= nrm;
this.y /= nrm;
this.z /= nrm;
}
returnthis;
},
smul:function(k) {
this.x *= k;
this.y *= k;
this.z *= k;
returnthis;
},
dpWith:function(v) {
returnthis.x*v.x +this.y*v.y +this.z*v.z;
},
cp:function(v, w) {
this.x = (w.y * v.z) - (w.z * v.y);
this.y = (w.z * v.x) - (w.x * v.z);
this.z = (w.x * v.y) - (w.y * v.x);
returnthis;
},
toString:function() {
returnthis.x +", "+this.y +","+this.z;
}
}
functionM44(cpy)
{
if(cpy)
this.copyFrom(cpy);
else{
this.ident();
}
}
M44.prototype = {
ident:function() {
this._12 =this._13 =this._14 = 0;
this._21 =this._23 =this._24 = 0;
this._31 =this._32 =this._34 = 0;
this._41 =this._42 =this._43 = 0;
this._11 =this._22 =this._33 =this._44 = 1;
returnthis;
},
copyFrom:function(m) {
this._11 = m._11;
this._12 = m._12;
this._13 = m._13;
this._14 = m._14;
this._21 = m._21;
this._22 = m._22;
this._23 = m._23;
this._24 = m._24;
this._31 = m._31;
this._32 = m._32;
this._33 = m._33;
this._34 = m._34;
this._41 = m._41;
this._42 = m._42;
this._43 = m._43;
this._44 = m._44;
returnthis;
},
transVec3:function(out, x, y, z) {
out[0] = x *this._11 + y *this._21 + z *this._31 +this._41;
out[1] = x *this._12 + y *this._22 + z *this._32 +this._42;
out[2] = x *this._13 + y *this._23 + z *this._33 +this._43;
out[3] = x *this._14 + y *this._24 + z *this._34 +this._44;
},
transVec3Rot:function(out, x, y, z) {
out[0] = x *this._11 + y *this._21 + z *this._31;
out[1] = x *this._12 + y *this._22 + z *this._32;
out[2] = x *this._13 + y *this._23 + z *this._33;
},
perspectiveLH:function(vw, vh, z_near, z_far) {
this._11 = 2.0*z_near/vw;
this._12 = 0;
this._13 = 0;
this._14 = 0;
this._21 = 0;
this._22 = 2*z_near/vh;
this._23 = 0;
this._24 = 0;
this._31 = 0;
this._32 = 0;
this._33 = z_far/(z_far-z_near);
this._34 = 1;
this._41 = 0;
this._42 = 0;
this._43 = z_near*z_far/(z_near-z_far);
this._44 = 0;
returnthis;
},
lookAtLH:function(aUp, aFrom, aAt) {
varaX =newVec3();
varaY =newVec3();
varaZ =newVec3(aAt.x, aAt.y, aAt.z);
aZ.sub(aFrom).normalize();
aX.cp(aUp, aZ).normalize();
aY.cp(aZ, aX);
this._11 = aX.x;this._12 = aY.x;this._13 = aZ.x;this._14 = 0;
this._21 = aX.y;this._22 = aY.y;this._23 = aZ.y;this._24 = 0;
this._31 = aX.z;this._32 = aY.z;this._33 = aZ.z;this._34 = 0;
this._41 = -aFrom.dpWith(aX);
this._42 = -aFrom.dpWith(aY);
this._43 = -aFrom.dpWith(aZ);
this._44 = 1;
returnthis;
},
mul:function(A, B) {
this._11 = A._11*B._11 + A._12*B._21 + A._13*B._31 + A._14*B._41;
this._12 = A._11*B._12 + A._12*B._22 + A._13*B._32 + A._14*B._42;
this._13 = A._11*B._13 + A._12*B._23 + A._13*B._33 + A._14*B._43;
this._14 = A._11*B._14 + A._12*B._24 + A._13*B._34 + A._14*B._44;
this._21 = A._21*B._11 + A._22*B._21 + A._23*B._31 + A._24*B._41;
this._22 = A._21*B._12 + A._22*B._22 + A._23*B._32 + A._24*B._42;
this._23 = A._21*B._13 + A._22*B._23 + A._23*B._33 + A._24*B._43;
this._24 = A._21*B._14 + A._22*B._24 + A._23*B._34 + A._24*B._44;
this._31 = A._31*B._11 + A._32*B._21 + A._33*B._31 + A._34*B._41;
this._32 = A._31*B._12 + A._32*B._22 + A._33*B._32 + A._34*B._42;
this._33 = A._31*B._13 + A._32*B._23 + A._33*B._33 + A._34*B._43;
this._34 = A._31*B._14 + A._32*B._24 + A._33*B._34 + A._34*B._44;
this._41 = A._41*B._11 + A._42*B._21 + A._43*B._31 + A._44*B._41;
this._42 = A._41*B._12 + A._42*B._22 + A._43*B._32 + A._44*B._42;
this._43 = A._41*B._13 + A._42*B._23 + A._43*B._33 + A._44*B._43;
this._44 = A._41*B._14 + A._42*B._24 + A._43*B._34 + A._44*B._44;
returnthis;
},
translate:function(x, y, z) {
this._11 = 1;this._12 = 0;this._13 = 0;this._14 = 0;
this._21 = 0;this._22 = 1;this._23 = 0;this._24 = 0;
this._31 = 0;this._32 = 0;this._33 = 1;this._34 = 0;
this._41 = x;this._42 = y;this._43 = z;this._44 = 1;
returnthis;
},
transpose33:function() {
vart;
t =this._12;
this._12 =this._21;
this._21 = t;
t =this._13;
this._13 =this._31;
this._31 = t;
t =this._23;
this._23 =this._32;
this._32 = t;
returnthis;
},
// OpenGL style rotation
glRotate:function(angle, x, y, z) {
vars = Math.sin( angle );
varc = Math.cos( angle );
varxx = x * x;
varyy = y * y;
varzz = z * z;
varxy = x * y;
varyz = y * z;
varzx = z * x;
varxs = x * s;
varys = y * s;
varzs = z * s;
varone_c = 1.0 - c;
/*
this._11 = (one_c * xx) + c;
this._21 = (one_c * xy) - zs;
this._31 = (one_c * zx) + ys;
this._41 = 0;
this._12 = (one_c * xy) + zs;
this._22 = (one_c * yy) + c;
this._32 = (one_c * yz) - xs;
this._42 = 0;
this._13 = (one_c * zx) - ys;
this._23 = (one_c * yz) + xs;
this._33 = (one_c * zz) + c;
this._43 = 0;