1 /**
  2  * The Render Engine
  3  * Transform2DComponent
  4  *
  5  * @fileoverview The base 2d transformation component.
  6  *
  7  * @author: Brett Fattori (brettf@renderengine.com)
  8  * @author: $Author: bfattori $
  9  * @version: $Revision: 1555 $
 10  *
 11  * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 12  *
 13  * Permission is hereby granted, free of charge, to any person obtaining a copy
 14  * of this software and associated documentation files (the "Software"), to deal
 15  * in the Software without restriction, including without limitation the rights
 16  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 17  * copies of the Software, and to permit persons to whom the Software is
 18  * furnished to do so, subject to the following conditions:
 19  *
 20  * The above copyright notice and this permission notice shall be included in
 21  * all copies or substantial portions of the Software.
 22  *
 23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 26  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 28  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 29  * THE SOFTWARE.
 30  *
 31  */
 32 
 33 // The class this file defines and its required classes
 34 R.Engine.define({
 35     "class":"R.components.Transform2D",
 36     "requires":[
 37         "R.components.Base",
 38         "R.math.Math2D",
 39         "R.math.Point2D",
 40         "R.math.Vector2D"
 41     ]
 42 });
 43 
 44 /**
 45  * @class A simple component that maintains position, rotation, and scale.
 46  *
 47  * @param name {String} The name of the component
 48  * @param [priority=1.0] {Number} The priority of the component
 49  * @extends R.components.Base
 50  * @constructor
 51  * @description Create a 2d transformation component
 52  */
 53 R.components.Transform2D = function () {
 54     "use strict";
 55     return R.components.Base.extend(/** @scope R.components.Transform2D.prototype */{
 56 
 57         position:null,
 58         rotation:0,
 59         scale:null,
 60         lastPosition:null,
 61         lastRenderPosition:null,
 62         worldPos:null,
 63 
 64         /* pragma:DEBUG_START */
 65         _up:null,
 66         _left:null,
 67         /* pragma:DEBUG_END */
 68 
 69         /**
 70          * @private
 71          */
 72         constructor:function (name, priority) {
 73             this.base(name, R.components.Base.TYPE_TRANSFORM, priority || 1.0);
 74             this.position = R.math.Point2D.create(0, 0);
 75             this.worldPos = R.math.Point2D.create(0, 0);
 76             this.lastPosition = R.math.Point2D.create(0, 0);
 77             this.lastRenderPosition = R.math.Point2D.create(0, 0);
 78             this.rotation = 0;
 79             this.scale = R.math.Vector2D.create(1, 1);
 80 
 81             /* pragma:DEBUG_START */
 82             this._up = R.math.Vector2D.create(R.math.Vector2D.UP).mul(10);
 83             this._left = R.math.Vector2D.create(R.math.Vector2D.LEFT).mul(10);
 84             /* pragma:DEBUG_END */
 85 
 86         },
 87 
 88         /**
 89          * Destroy the component instance
 90          */
 91         destroy:function () {
 92             this.position.destroy();
 93             this.worldPos.destroy();
 94             this.lastPosition.destroy();
 95             this.lastRenderPosition.destroy();
 96 
 97             /* pragma:DEBUG_START */
 98             this._up.destroy();
 99             this._left.destroy();
100             /* pragma:DEBUG_END */
101 
102             this.base();
103         },
104 
105         /**
106          * Releases the component back into the object pool. See {@link PooledObject#release} for
107          * more information.
108          */
109         release:function () {
110             this.base();
111             this.position = null;
112             this.rotation = 0;
113             this.scale = null;
114             this.lastPosition = null;
115             this.lastRenderPosition = null;
116             this.worldPos = null;
117         },
118 
119         /**
120          * Set the position of the transform.
121          *
122          * @param point {Number|R.math.Point2D} The X coordinate, or the position
123          * @param [y] {Number} If <tt>point</tt> was a number, this is the Y coordinate
124          */
125         setPosition:function (point, y) {
126             this.setLastPosition(this.getPosition());
127             this.position.set(point, y);
128             this.getGameObject().markDirty();
129         },
130 
131         /**
132          * Returns the position of the transformation relative to the world.
133          * @return {R.math.Point2D}
134          */
135         getPosition:function () {
136             return this.position;
137         },
138 
139         /**
140          * Returns the position of the transformation relative to the viewport.  If the world is
141          * comprised of multiple viewports (wide and/or tall) the render position
142          * is relative to the current viewport's position.
143          * @return {R.math.Point2D}
144          */
145         getRenderPosition:function () {
146             this.worldPos.set(this.getPosition());
147             this.worldPos.sub(this.getGameObject().getRenderContext().getWorldPosition());
148             return this.worldPos;
149         },
150 
151         /**
152          * Set the last position that the transformation was at.
153          *
154          * @param point {Number|R.math.Point2D} The last X coordinate, or last position
155          * @param [y] {Number} If <code>point</code> was a number, this is the Y coordinate
156          */
157         setLastPosition:function (point, y) {
158             this.lastPosition.set(point, y);
159         },
160 
161         /**
162          * Get the last position of the transformation relative to the world.
163          * @return {R.math.Point2D}
164          */
165         getLastPosition:function () {
166             return this.lastPosition;
167         },
168 
169         /**
170          * Get the last position of the transformation relative to the viewport.
171          * @return {R.math.Point2D}
172          */
173         getLastRenderPosition:function () {
174             return this.lastRenderPosition;
175         },
176 
177         /**
178          * Set the rotation of the transformation.
179          *
180          * @param rotation {Number} The rotation
181          */
182         setRotation:function (rotation) {
183             this.rotation = rotation;
184             this.getGameObject().markDirty();
185         },
186 
187         /**
188          * Get the rotation of the transformation.
189          * @return {Number}
190          */
191         getRotation:function () {
192             return this.rotation;
193         },
194 
195         /**
196          * Get the rotation of the transformation relative to the viewport.
197          * @return {Number}
198          */
199         getRenderRotation:function () {
200             var wR = this.getGameObject().getRenderContext().getWorldRotation();
201             return wR + this.getRotation();
202         },
203 
204         /**
205          * Set the scale of the transform.  You can apply a uniform scale by
206          * assigning only the first argument a value.  To use a non-uniform scale,
207          * use both the X and Y arguments.
208          *
209          * @param scaleX {Number} The scale of the transformation along the X-axis with 1.0 being 100%
210          * @param [scaleY] {Number} The scale of the transformation along the Y-axis. If provided, a
211          *            non-uniform scale can be achieved by using a number which differs from the X-axis.
212          */
213         setScale:function (scaleX, scaleY) {
214             scaleX = scaleX || 1.0;
215             this.scale.set(scaleX, scaleY || scaleX);
216             this.getGameObject().markDirty();
217         },
218 
219         /**
220          * Get the uniform scale of the transformation.
221          * @return {Number}
222          */
223         getScale:function () {
224             return this.scale;
225         },
226 
227         /**
228          * Get the non-uniform scale along the X-axis of the transformation.
229          * @return {Number}
230          */
231         getScaleX:function () {
232             return this.scale.x;
233         },
234 
235         /**
236          * Get the non-uniform scale along the Y-axis of the transformation.
237          * @return {Number}
238          */
239         getScaleY:function () {
240             return this.scale.y;
241         },
242 
243         /**
244          * Get the uniform scale of the transformation relative to the viewport.
245          * @return {Number}
246          */
247         getRenderScale:function () {
248 //    var wS = this.getGameObject().getRenderContext().getWorldScale();
249 //      return wS * this.scale;
250             return this.scale;
251         },
252 
253         /**
254          * Get the uniform scale of the transformation relative to the viewport along the X-axis.
255          * @return {Number}
256          */
257         getRenderScaleX:function () {
258 //    var wS = this.getGameObject().getRenderContext().getWorldScale();
259 //      return wS * this.scale;
260             return this.scale.x;
261         },
262 
263         /**
264          * Get the uniform scale of the transformation relative to the viewport along the Y-axis.
265          * @return {Number}
266          */
267         getRenderScaleY:function () {
268 //    var wS = this.getGameObject().getRenderContext().getWorldScale();
269 //      return wS * this.scale;
270             return this.scale.y;
271         },
272 
273         /**
274          * Set the components of a transformation: position, rotation,
275          * and scale, within the rendering context.
276          *
277          * @param renderContext {R.rendercontexts.AbstractRenderContext} The rendering context
278          * @param time {Number} The engine time in milliseconds
279          * @param dt {Number} The delta between the world time and the last time the world was updated
280          *          in milliseconds.
281          */
282         execute:function (renderContext, time, dt) {
283             // TODO: This should really be in a render component only
284             renderContext.setPosition(this.getRenderPosition());
285             renderContext.setRotation(this.getRenderRotation());
286             renderContext.setScale(this.scale.x, this.scale.y);
287 
288             /* pragma:DEBUG_START */
289             // Debug the origin
290             if (R.Engine.getDebugMode()) {
291                 renderContext.setLineWidth(1);
292                 renderContext.setLineStyle("#f00");
293                 renderContext.drawLine(R.math.Point2D.ZERO, this._up);
294                 renderContext.setLineStyle("#08f");
295                 renderContext.drawLine(R.math.Point2D.ZERO, this._left);
296             }
297             /* pragma:DEBUG_END */
298         }
299 
300     }, /** @scope R.components.Transform2D.prototype */{
301         /**
302          * Get the class name of this object
303          *
304          * @return {String} "R.components.Transform2D"
305          */
306         getClassName:function () {
307             return "R.components.Transform2D";
308         }
309     });
310 };