diff options
Diffstat (limited to 'js/helper-classes/RDGE/src/core/script/camera.js')
-rw-r--r-- | js/helper-classes/RDGE/src/core/script/camera.js | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/js/helper-classes/RDGE/src/core/script/camera.js b/js/helper-classes/RDGE/src/core/script/camera.js new file mode 100644 index 00000000..caff232b --- /dev/null +++ b/js/helper-classes/RDGE/src/core/script/camera.js | |||
@@ -0,0 +1,251 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | /* | ||
7 | * camera class | ||
8 | */ | ||
9 | camera = function() { | ||
10 | this.proj = mat4.identity(); | ||
11 | this.view = mat4.identity(); | ||
12 | this.world = mat4.identity(); | ||
13 | this.viewProj = mat4.identity(); | ||
14 | this.invViewProj = mat4.identity(); | ||
15 | this.frustum = []; | ||
16 | this.frustumPts = []; | ||
17 | this.controller = null; | ||
18 | |||
19 | this.setPerspective = function(fov, aratio, near, far) | ||
20 | { | ||
21 | this.ortho = null; | ||
22 | this.persp = {}; | ||
23 | this.persp.fov = fov; | ||
24 | this.persp.aratio = aratio; | ||
25 | this.persp.near = near; | ||
26 | this.persp.far = far; | ||
27 | this.proj = mat4.perspective(fov, aratio, near, far); | ||
28 | this.recalc(); | ||
29 | } | ||
30 | |||
31 | this.reset = function() { | ||
32 | this.world = mat4.identity(); | ||
33 | this.recalc(); | ||
34 | } | ||
35 | |||
36 | this.copy = function(cam) { | ||
37 | mat4.inplace_copy(this.view, cam.view); | ||
38 | mat4.inplace_copy(this.world, cam.world); | ||
39 | mat4.inplace_copy(this.proj, cam.proj); | ||
40 | mat4.inplace_copy(this.viewProj, cam.viewProj); | ||
41 | mat4.inplace_copy(this.invViewProj, cam.invViewProj); | ||
42 | this.frustum = cam.frustum.slice(); | ||
43 | this.frustumPts = cam.frustumPts.slice(); | ||
44 | } | ||
45 | |||
46 | this.recalc = function() { | ||
47 | // update frustum planes | ||
48 | this.frustum = []; | ||
49 | var vp = this.viewProj; | ||
50 | |||
51 | normalizePlane = function( p ) { | ||
52 | var len = vec3.length( p ); | ||
53 | if( Math.abs( 1.0 - len ) > 0.001 ) { | ||
54 | p[0] /= len; | ||
55 | p[1] /= len; | ||
56 | p[2] /= len; | ||
57 | p[3] /= len; | ||
58 | } | ||
59 | return p; | ||
60 | } | ||
61 | |||
62 | /* This is the old way | ||
63 | var t = this.persp.near * Math.tan(0.017453292519943295769236 * this.persp.fov * 0.5); | ||
64 | var r = t * this.persp.aratio; | ||
65 | var u = t; | ||
66 | var l = -r; | ||
67 | var b = -u; | ||
68 | |||
69 | tview = mat4.transpose(this.view); | ||
70 | this.frustum.push( normalizePlane( mat4.transformPoint(tview, [this.persp.near, 0.0, l, 0.0] ) ) ); // left | ||
71 | this.frustum.push( normalizePlane( mat4.transformPoint(tview, [-this.persp.near, 0.0, -r, 0.0] ) ) ); // right | ||
72 | this.frustum.push( normalizePlane( mat4.transformPoint(tview, [0.0, this.persp.near, b, 0.0] ) ) ); // bottom | ||
73 | this.frustum.push( normalizePlane( mat4.transformPoint(tview, [0.0, -this.persp.near, -u, 0.0] ) ) ); // top | ||
74 | this.frustum.push( normalizePlane( mat4.transformPoint(tview, [0.0, 0.0, -1.0, -this.persp.near] ) ) ); // near | ||
75 | this.frustum.push( normalizePlane( mat4.transformPoint(tview, [0.0, 0.0, 1.0, this.persp.far] ) ) ); // far | ||
76 | */ | ||
77 | var l = normalizePlane( [vp[3] + vp[0], vp[7] + vp[4], vp[11] + vp[8], vp[15]+vp[12]] ); | ||
78 | var r = normalizePlane( [vp[3] - vp[0], vp[7] - vp[4], vp[11] - vp[8], vp[15]-vp[12]] ); | ||
79 | var t = normalizePlane( [vp[3] - vp[1], vp[7] - vp[5], vp[11] - vp[9], vp[15]-vp[13]] ); | ||
80 | var b = normalizePlane( [vp[3] + vp[1], vp[7] + vp[5], vp[11] + vp[9], vp[15]+vp[13]] ); | ||
81 | var n = normalizePlane( [vp[3] + vp[2], vp[7] + vp[6], vp[11] + vp[10], vp[15]+vp[14]] ); | ||
82 | var f = normalizePlane( [vp[3] - vp[2], vp[7] - vp[6], vp[11] - vp[10], vp[15]-vp[14]] ); | ||
83 | |||
84 | this.frustum.push(l); | ||
85 | this.frustum.push(r); | ||
86 | this.frustum.push(t); | ||
87 | this.frustum.push(b); | ||
88 | this.frustum.push(n); | ||
89 | this.frustum.push(f); | ||
90 | |||
91 | // update frustum points | ||
92 | this.frustumPts = []; | ||
93 | var invvp = this.viewProj; | ||
94 | this.frustumPts.push( mat4.transformPoint( invvp, [-1,-1,-1] ) ); | ||
95 | this.frustumPts.push( mat4.transformPoint( invvp, [-1,1,-1] ) ); | ||
96 | this.frustumPts.push( mat4.transformPoint( invvp, [1,1,-1] ) ); | ||
97 | this.frustumPts.push( mat4.transformPoint( invvp, [1,-1,-1] ) ); | ||
98 | this.frustumPts.push( mat4.transformPoint( invvp, [-1,-1,1] ) ); | ||
99 | this.frustumPts.push( mat4.transformPoint( invvp, [-1,1,1] ) ); | ||
100 | this.frustumPts.push( mat4.transformPoint( invvp, [1,1,1] ) ); | ||
101 | this.frustumPts.push( mat4.transformPoint( invvp, [1,-1,1] ) ); | ||
102 | }; | ||
103 | |||
104 | this.setWorld = function(m) { | ||
105 | this.world = m; | ||
106 | this.view = mat4.inverse(m); | ||
107 | this.viewProj = mat4.mul( this.view, this.proj ); | ||
108 | this.invViewProj = mat4.inverse(this.viewProj); | ||
109 | this.recalc(); | ||
110 | } | ||
111 | |||
112 | this.setView = function(m) { | ||
113 | this.view = m; | ||
114 | this.world = mat4.inverse(m); | ||
115 | this.viewProj = mat4.mul( this.view, this.proj ); | ||
116 | this.invViewProj = mat4.inverse(this.viewProj); | ||
117 | this.recalc(); | ||
118 | } | ||
119 | |||
120 | this.setLookAt = function(eyePos, targetPos, upVec) { | ||
121 | this.setWorld( mat4.lookAt(eyePos, targetPos, upVec) ); | ||
122 | //this.recalc(); | ||
123 | }; | ||
124 | |||
125 | this.setPerspective = function(fov, aratio, near, far) { | ||
126 | this.ortho = null; | ||
127 | this.persp = {}; | ||
128 | this.persp.fov = fov; | ||
129 | this.persp.aratio = aratio; | ||
130 | this.persp.near = near; | ||
131 | this.persp.far = far; | ||
132 | this.proj = mat4.perspective(fov, aratio, near, far); | ||
133 | this.recalc(); | ||
134 | } | ||
135 | |||
136 | this.setOrthographic = function( l, r, t, b, n, f ) { | ||
137 | this.persp = null; | ||
138 | this.ortho = {}; | ||
139 | this.ortho.left = l; | ||
140 | this.ortho.right = r; | ||
141 | this.ortho.top = t; | ||
142 | this.ortho.bottom = b; | ||
143 | this.ortho.near = n; | ||
144 | this.ortho.far = f; | ||
145 | this.proj = mat4.orthographic(l, r, t, b, n, f); | ||
146 | this.recalc(); | ||
147 | } | ||
148 | |||
149 | this.onResize = function(x, y, width, height) { | ||
150 | if( this.persp ) { | ||
151 | this.setPerspective(this.persp.fov, width / height, this.persp.near, this.persp.far); | ||
152 | } | ||
153 | if( this.ortho ) { | ||
154 | this.setOrthographic(x, x + width, y, y + height, this.ortho.near, this.ortho.far); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | this.zNear = function() { | ||
159 | if( this.persp ) { | ||
160 | return this.persp.near; | ||
161 | } | ||
162 | |||
163 | if( this.ortho ) { | ||
164 | return this.ortho.near; | ||
165 | } | ||
166 | |||
167 | return 0.0; | ||
168 | } | ||
169 | |||
170 | this.zFar = function() { | ||
171 | if( this.persp ) { | ||
172 | return this.persp.far; | ||
173 | } | ||
174 | |||
175 | if( this.ortho ) { | ||
176 | return this.ortho.far; | ||
177 | } | ||
178 | |||
179 | return 0.0; | ||
180 | } | ||
181 | |||
182 | // this is used by ambient occlusion... | ||
183 | this.getFTR = function() { | ||
184 | var fovyRad = (this.persp.fov * 0.5) * Math.PI / 180.0; | ||
185 | return [ | ||
186 | Math.tan(fovyRad) * this.persp.far, | ||
187 | Math.tan(fovyRad / this.persp.aratio) * this.persp.far, | ||
188 | this.persp.far ]; | ||
189 | } | ||
190 | |||
191 | this.attachCameraToNode = function( node ) | ||
192 | { | ||
193 | this.controller = node; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | |||
198 | /** Camera Manager | ||
199 | * This class is used to manage the active camera. It provides functionality | ||
200 | * for getting and setting the active camera, as well as providing stack operations | ||
201 | * to switch to and from multiple cameras. | ||
202 | */ | ||
203 | cameraManager = function() { | ||
204 | this.stack = []; | ||
205 | |||
206 | /* Set the active camera. | ||
207 | * This function sets the active camera to the given camera. | ||
208 | */ | ||
209 | this.setActiveCamera = function(c) { | ||
210 | // pop the active camera off the stack. | ||
211 | if( this.stack.length > 0 ) { | ||
212 | this.stack.pop(); | ||