jacobinathanialpeterson's picture
Upload 1035 files
1e40c2a
raw
history blame
6.85 kB
/*
* Javascript/Canvas Textured 3D Renderer v0.3.1
* Copyright (c) 2008 Jacob Seidelin, [email protected]
* This software is free to use for non-commercial purposes. For anything else, please contact the author.
* This is a version modified by Stefano Gioffre'.
*/
Canvas3D.Camera = function() {
this._oPosition = new Canvas3D.Vec3(0,0,0);
this._oSideVec = new Canvas3D.Vec3(1,0,0);
this._oUpVec = new Canvas3D.Vec3(0,1,0);
this._oOutVec = new Canvas3D.Vec3(0,0,1);
this._oRotMat = new Canvas3D.Matrix3();
this._bDirty = false;
this._fFocal = 500;
this._fFocalDistance = this._fFocal;
this._bReverseX = false;
this._bReverseY = false;
this._bTarget = true;
this._iClipNear = 1;
this._iClipFar = 10000000;
this._fScale = 1;
this._oLookAt = new Canvas3D.Vec3(0,0,0);
};
var proto = Canvas3D.Camera.prototype;
proto.getDirty = function() {
return this._bDirty;
}
proto.setDirty = function(bDirty) {
this._bDirty = bDirty;
}
proto.setPosition = function(oPos) {
this._oPosition.set(oPos.x, oPos.y, oPos.z);
this._bDirty = true;
}
proto.getPosition = function() {
return this._oPosition;
}
proto.setScale = function(fScale) {
this._fScale = fScale;
this._bDirty = true;
}
proto.getScale = function() {
return this._fScale;
}
proto.getSide = function() {
return this._oSideVec;
}
proto.getUp = function() {
return this._oUpVec;
}
proto.setUp = function(oVec) {
this._oUpVec = oVec;
}
proto.getOut = function() {
return this._oOutVec;
}
proto.moveSideways = function(d) {
this._oPosition.x += this._oSideVec.x * d;
this._oPosition.y += this._oSideVec.y * d;
this._oPosition.z += this._oSideVec.z * d;
this.setDirty(true);
}
proto.moveUpwards = function(d) {
this._oPosition.x += this._oUpVec.x * d;
this._oPosition.y += this._oUpVec.y * d;
this._oPosition.z += this._oUpVec.z * d;
this.setDirty(true);
}
proto.moveForward = function(d) {
this._oPosition.x += this._oOutVec.x * d;
this._oPosition.y += this._oOutVec.y * d;
this._oPosition.z += this._oOutVec.z * d;
this.setDirty(true);
}
// rotate around the camera's side axis with a target center point (uses camera target if oTarget is null)
proto.pitchAroundTarget = function(fTheta, oTarget) {
var M = new Canvas3D.Matrix3();
var oPos = this.getPosition();
oTarget = oTarget || this.getLookAt();
// translate position to target space
oPos.subVector(oTarget);
// rotate around side axis
M.loadRotationAxis(this._oSideVec, Math.sin(fTheta * Math.PI / 180.0), Math.cos(fTheta * Math.PI / 180.0));
oPos = M.multiplyVector(oPos);
// translate position out of target space
oPos.addVector(oTarget);
this.setPosition(oPos);
this.setDirty(true);
}
proto.yaw = function(fTheta) {
var M = new Canvas3D.Matrix3();
M.loadRotationAxis(this._oUpVec, Math.sin(fTheta), Math.cos(fTheta));
this._oSideVec = M.multiplyVector(this._oSideVec);
this._oOutVec = M.multiplyVector(this._oOutVec);
this.setDirty(true);
}
// rotate around the camera's up axis with a target center point (uses camera target if oTarget is null)
proto.yawAroundTarget = function(fTheta, oTarget) {
var M = new Canvas3D.Matrix3();
var oPos = this.getPosition();
oTarget = oTarget || this.getLookAt();
// translate position to target space
oPos.subVector(oTarget);
// rotate around up axis
M.loadRotationAxis(this._oUpVec, Math.sin(fTheta * Math.PI / 180.0), Math.cos(fTheta * Math.PI / 180.0));
oPos = M.multiplyVector(oPos);
// translate position out of target space
oPos.addVector(oTarget);
this.setPosition(oPos);
this.setDirty(true);
}
// rotate around the camera's out axis with a target center point (uses camera target if oTarget is null)
proto.rollAroundTarget = function(fTheta, oTarget) {
var M = new Canvas3D.Matrix3();
var oPos = this.getPosition();
oTarget = oTarget || this.getLookAt();
// translate position to target space
oPos.subVector(oTarget);
// rotate around out axis
M.loadRotationAxis(this._oOutVec, Math.sin(fTheta * Math.PI / 180.0), Math.cos(fTheta * Math.PI / 180.0));
oPos = M.multiplyVector(oPos);
// translate position out of target space
oPos.addVector(oTarget);
this.setPosition(oPos);
this.setDirty(true);
}
proto.rotateY = function(sine, cosine) {
var M = new Canvas3D.Matrix3();
M.loadRotationY(sine, cosine);
this._oSideVec = M.multiplyVector(this._oSideVec);
this._oUpVec = M.multiplyVector(this._oUpVec);
this._oOutVec = M.multiplyVector(this._oOutVec);
this.setDirty(true);
}
proto.lookAt = function(P, Up) {
Up = Up || this._oUpVec;
this._oOutVec = P.returnSub(this._oPosition).unit();
//this._oSideVec = this._oOutVec.cross(new Canvas3D.Vec3 (0.0, 1.0, 0.0)).unit();
//this._oSideVec = this._oOutVec.cross(this._oUpVec).unit();
this._oSideVec = this._oOutVec.cross(Up).unit();
this._oUpVec = this._oSideVec.cross(this._oOutVec).unit();
this._vecLookAt = P.clone();
this.setDirty(true);
}
proto.getLookAt = function() {
return this._vecLookAt;
}
proto.updateRotationMatrix = function() {
var e0 = this._oRotMat.e[0];
var e1 = this._oRotMat.e[1];
var e2 = this._oRotMat.e[2];
e0[0] = this._oSideVec.x;
e0[1] = this._oSideVec.y;
e0[2] = this._oSideVec.z;
e1[0] = this._oUpVec.x;
e1[1] = this._oUpVec.y;
e1[2] = this._oUpVec.z;
e2[0] = this._oOutVec.x;
e2[1] = this._oOutVec.y;
e2[2] = this._oOutVec.z;
}
proto.transformPoint = function(P) {
var e = this._oRotMat.e;
var oPos = this._oPosition;
var e0 = e[0];
var e1 = e[1];
var e2 = e[2];
var vx = P.x - oPos.x;
var vy = P.y - oPos.y;
var vz = P.z - oPos.z;
return new Canvas3D.Vec3(
(vx * e0[0] + vy * e0[1] + vz * e0[2]),
(vx * e1[0] + vy * e1[1] + vz * e1[2]),
(vx * e2[0] + vy * e2[1] + vz * e2[2])
);
}
proto.project = function(P) {
var fFocal = this._fFocal;
return {
x: P.x * fFocal / (P.z + this._fFocalDistance) * this._fScale * (this._bReverseX?-1:1),
y: -P.y * fFocal / (P.z + this._fFocalDistance) * this._fScale * (this._bReverseY?-1:1)
};
}
proto.clip = function(P) {
if (P.z < 0) {
return true;
}
return false;
}
proto.isBehind = function(P) {
if (P.z > 0) return false;
return false;
}
proto.getClipNear = function() {
return this._iClipNear;
}
proto.getClipFar = function() {
return this._iClipFar;
}
proto.clip = function(P) {
if (P.z > this._iClipNear && P.z < this._iClipFar) {
return false;
} else {
return true;
}
}
proto.setFOV = function(fFOV) {
this._fFOV = fFOV;
var fFocal = 1 / Math.tan(105 * Math.PI*Math.PI / (180*180 * 2));
this._fFocal = fFocal;
this._fFocalDistance = fFocal;
}
proto.getFOV = function() {
return this._fFOV;
}
proto.getFocal = function() {
return this._fFocal;
}
proto.setFocalDistance = function(fValue) {
this._fFocalDistance = fValue;
}
proto.setReverseX = function(bEnable) {
this._bReverseX = bEnable;
}
proto.setReverseY = function(bEnable) {
this._bReverseY = bEnable;
}