1 /****************************************************************************
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 /**
 28  * <p>
 29  *     A CCCamera is used in every CCNode.                                                                                 <br/>
 30  *     The OpenGL gluLookAt() function is used to locate the camera.                                                       <br/>
 31  *                                                                                                                         <br/>
 32  *     If the object is transformed by any of the scale, rotation or position attributes, then they will override the camera.          <br/>
 33  *                                                                                                                                     <br/>
 34  *     IMPORTANT: Either your use the camera or the rotation/scale/position properties. You can't use both.                            <br/>
 35  *     World coordinates won't work if you use the camera.                                                                             <br/>
 36  *                                                                                                                                     <br/>
 37  *     Limitations:                                                                                                                    <br/>
 38  *     - Some nodes, like CCParallaxNode, CCParticle uses world node coordinates, and they won't work properly if you move them (or any of their ancestors)           <br/>
 39  *     using the camera.                                                                                                               <br/>
 40  *                                                                                                                                     <br/>
 41  *     - It doesn't work on batched nodes like CCSprite objects when they are parented to a CCSpriteBatchNode object.                  <br/>
 42  *                                                                                                                                     <br/>
 43  *     - It is recommended to use it ONLY if you are going to create 3D effects. For 2D effecs, use the action CCFollow or position/scale/rotate. *
 44  * </p>
 45  */
 46 cc.Camera = cc.Class.extend({
 47     _eyeX:null,
 48     _eyeY:null,
 49     _eyeZ:null,
 50 
 51     _centerX:null,
 52     _centerY:null,
 53     _centerZ:null,
 54 
 55     _upX:null,
 56     _upY:null,
 57     _upZ:null,
 58 
 59     _dirty:false,
 60     _lookupMatrix:null,
 61     /**
 62      * constructor of cc.Camera
 63      */
 64     ctor:function () {
 65         this._lookupMatrix = new cc.math.Matrix4();
 66         this.restore();
 67     },
 68 
 69     /**
 70      * Description of cc.Camera
 71      * @return {String}
 72      */
 73     description:function () {
 74         return "<CCCamera | center =(" + this._centerX + "," + this._centerY + "," + this._centerZ + ")>";
 75     },
 76 
 77     /**
 78      * sets the dirty value
 79      * @param value
 80      */
 81     setDirty:function (value) {
 82         this._dirty = value;
 83     },
 84 
 85     /**
 86      * get the dirty value
 87      * @return {Boolean}
 88      */
 89     isDirty:function () {
 90         return this._dirty;
 91     },
 92 
 93     /**
 94      * sets the camera in the default position
 95      */
 96     restore:function () {
 97         this._eyeX = this._eyeY = 0.0;
 98         this._eyeZ = cc.Camera.getZEye();
 99 
100         this._centerX = this._centerY = this._centerZ = 0.0;
101 
102         this._upX = 0.0;
103         this._upY = 1.0;
104         this._upZ = 0.0;
105 
106         this._lookupMatrix.identity();
107 
108         this._dirty = false;
109     },
110 
111     /**
112      * Sets the camera using gluLookAt using its eye, center and up_vector
113      */
114     locate:function () {
115         if (this._dirty) {
116             var eye = new cc.math.Vec3(this._eyeX, this._eyeY , this._eyeZ),
117                 center = new cc.math.Vec3(this._centerX, this._centerY, this._centerZ),
118                 up = new cc.math.Vec3(this._upX, this._upY, this._upZ);
119             this._lookupMatrix.lookAt(eye, center, up);
120             this._dirty = false;
121         }
122         cc.kmGLMultMatrix( this._lookupMatrix);
123     },
124 
125     _locateForRenderer: function(matrix){
126         if (this._dirty) {
127             var eye = new cc.math.Vec3(this._eyeX, this._eyeY , this._eyeZ),
128                 center = new cc.math.Vec3(this._centerX, this._centerY, this._centerZ),
129                 up = new cc.math.Vec3(this._upX, this._upY, this._upZ);
130             this._lookupMatrix.lookAt(eye, center, up);
131             this._dirty = false;
132         }
133         matrix.multiply(this._lookupMatrix);
134     },
135 
136     /**
137      * sets the eye values in points
138      * @param {Number} eyeX
139      * @param {Number} eyeY
140      * @param {Number} eyeZ
141      * @deprecated This function will be deprecated sooner or later please use setEye instead.
142      */
143     setEyeXYZ:function (eyeX, eyeY, eyeZ) {
144         this.setEye(eyeX,eyeY,eyeZ);
145     },
146 
147     /**
148      * sets the eye values in points
149      * @param {Number} eyeX
150      * @param {Number} eyeY
151      * @param {Number} eyeZ
152      */
153     setEye:function (eyeX, eyeY, eyeZ) {
154         this._eyeX = eyeX ;
155         this._eyeY = eyeY ;
156         this._eyeZ = eyeZ ;
157 
158         this._dirty = true;
159     },
160 
161     /**
162      * sets the center values in points
163      * @param {Number} centerX
164      * @param {Number} centerY
165      * @param {Number} centerZ
166      * @deprecated  This function will be deprecated sooner or later please use setCenter instead.
167      */
168     setCenterXYZ:function (centerX, centerY, centerZ) {
169         this.setCenter(centerX,centerY,centerZ);
170     },
171 
172     /**
173      * sets the center values in points
174      * @param {Number} centerX
175      * @param {Number} centerY
176      * @param {Number} centerZ
177      */
178     setCenter:function (centerX, centerY, centerZ) {
179         this._centerX = centerX ;
180         this._centerY = centerY ;
181         this._centerZ = centerZ ;
182 
183         this._dirty = true;
184     },
185 
186     /**
187      * sets the up values
188      * @param {Number} upX
189      * @param {Number} upY
190      * @param {Number} upZ
191      * @deprecated This function will be deprecated sooner or later.
192      */
193     setUpXYZ:function (upX, upY, upZ) {
194         this.setUp(upX, upY, upZ);
195     },
196 
197     /**
198      * sets the up values
199      * @param {Number} upX
200      * @param {Number} upY
201      * @param {Number} upZ
202      */
203     setUp:function (upX, upY, upZ) {
204         this._upX = upX;
205         this._upY = upY;
206         this._upZ = upZ;
207 
208         this._dirty = true;
209     },
210 
211     /**
212      * get the eye vector values in points  (return an object like {x:1,y:1,z:1} in HTML5)
213      * @param {Number} eyeX
214      * @param {Number} eyeY
215      * @param {Number} eyeZ
216      * @return {Object}
217      * @deprecated This function will be deprecated sooner or later, please use getEye instead.
218      */
219     getEyeXYZ:function (eyeX, eyeY, eyeZ) {
220         return {x:this._eyeX , y:this._eyeY , z: this._eyeZ };
221     },
222 
223     /**
224      * get the eye vector values in points  (return an object like {x:1,y:1,z:1} in HTML5)
225      * @return {Object}
226      */
227     getEye:function () {
228         return {x:this._eyeX , y:this._eyeY , z: this._eyeZ };
229     },
230 
231     /**
232      * get the center vector values int points (return an object like {x:1,y:1,z:1} in HTML5)
233      * @param {Number} centerX
234      * @param {Number} centerY
235      * @param {Number} centerZ
236      * @return {Object}
237      * @deprecated This function will be deprecated sooner or later,please use getCenter instead.
238      */
239     getCenterXYZ:function (centerX, centerY, centerZ) {
240         return {x:this._centerX ,y:this._centerY ,z:this._centerZ };
241     },
242 
243     /**
244      * get the center vector values int points (return an object like {x:1,y:1,z:1} in HTML5)
245      * @return {Object}
246      */
247     getCenter:function () {
248         return {x:this._centerX ,y:this._centerY ,z:this._centerZ };
249     },
250 
251     /**
252      * get the up vector values (return an object like {x:1,y:1,z:1} in HTML5)
253      * @param {Number} upX
254      * @param {Number} upY
255      * @param {Number} upZ
256      * @return {Object}
257      * @deprecated This function will be deprecated sooner or later,please use getUp instead.
258      */
259     getUpXYZ:function (upX, upY, upZ) {
260         return {x:this._upX,y:this._upY,z:this._upZ};
261     },
262 
263     /**
264      * get the up vector values (return an object like {x:1,y:1,z:1} in HTML5)
265      * @return {Object}
266      */
267     getUp:function () {
268         return {x:this._upX,y:this._upY,z:this._upZ};
269     },
270 
271     _DISALLOW_COPY_AND_ASSIGN:function (CCCamera) {
272 
273     }
274 });
275 
276 /**
277  * returns the Z eye
278  * @return {Number}
279  */
280 cc.Camera.getZEye = function () {
281     return cc.FLT_EPSILON;
282 };
283