All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.starling.display.Sprite3D.as Maven / Gradle / Ivy

// =================================================================================================
//
//	Starling Framework
//	Copyright 2011-2015 Gamua. All Rights Reserved.
//
//	This program is free software. You can redistribute and/or modify it
//	in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================

package starling.display
{
    import flash.geom.Matrix;
    import flash.geom.Matrix3D;
    import flash.geom.Point;
    import flash.geom.Vector3D;

    import starling.events.Event;
    import starling.rendering.Painter;
    import starling.utils.MathUtil;
    import starling.utils.MatrixUtil;
    import starling.utils.rad2deg;

    /** A container that allows you to position objects in three-dimensional space.
     *
     *  

Starling is, at its heart, a 2D engine. However, sometimes, simple 3D effects are * useful for special effects, e.g. for screen transitions or to turn playing cards * realistically. This class makes it possible to create such 3D effects.

* *

Positioning objects in 3D

* *

Just like a normal sprite, you can add and remove children to this container, which * allows you to group several display objects together. In addition to that, Sprite3D * adds some interesting properties:

* *
    *
  • z - Moves the sprite closer to / further away from the camera.
  • *
  • rotationX — Rotates the sprite around the x-axis.
  • *
  • rotationY — Rotates the sprite around the y-axis.
  • *
  • scaleZ - Scales the sprite along the z-axis.
  • *
  • pivotZ - Moves the pivot point along the z-axis.
  • *
* *

With the help of these properties, you can move a sprite and all its children in the * 3D space. By nesting several Sprite3D containers, it's even possible to construct simple * volumetric objects (like a cube).

* *

Note that Starling does not make any z-tests: visibility is solely established by the * order of the children, just as with 2D objects.

* *

Setting up the camera

* *

The camera settings are found directly on the stage. Modify the 'focalLength' or * 'fieldOfView' properties to change the distance between stage and camera; use the * 'projectionOffset' to move it to a different position.

* *

Limitations

* *

On rendering, each Sprite3D requires its own draw call — except if the object does not * contain any 3D transformations ('z', 'rotationX/Y' and 'pivotZ' are zero). Furthermore, * it interrupts the render cache, i.e. the cache cannot contain objects within different * 3D coordinate systems. Flat contents within the Sprite3D will be cached, though.

* */ public class Sprite3D extends DisplayObjectContainer { private static const E:Number = 0.00001; private var _rotationX:Number; private var _rotationY:Number; private var _scaleZ:Number; private var _pivotZ:Number; private var _z:Number; private var _transformationMatrix:Matrix; private var _transformationMatrix3D:Matrix3D; private var _transformationChanged:Boolean; private var _is2D:Boolean; /** Helper objects. */ private static var sHelperPoint:Vector3D = new Vector3D(); private static var sHelperPointAlt:Vector3D = new Vector3D(); private static var sHelperMatrix:Matrix3D = new Matrix3D(); /** Creates an empty Sprite3D. */ public function Sprite3D() { _scaleZ = 1.0; _rotationX = _rotationY = _pivotZ = _z = 0.0; _transformationMatrix = new Matrix(); _transformationMatrix3D = new Matrix3D(); _is2D = true; // meaning: this 3D object contains only 2D content setIs3D(true); // meaning: this display object supports 3D transformations addEventListener(Event.ADDED, onAddedChild); addEventListener(Event.REMOVED, onRemovedChild); } /** @inheritDoc */ public override function render(painter:Painter):void { if (_is2D) super.render(painter); else { painter.finishMeshBatch(); painter.pushState(); painter.state.transformModelviewMatrix3D(transformationMatrix3D); super.render(painter); painter.finishMeshBatch(); painter.popState(); } } /** @inheritDoc */ public override function hitTest(localPoint:Point):DisplayObject { if (_is2D) return super.hitTest(localPoint); else { if (!visible || !touchable) return null; // We calculate the interception point between the 3D plane that is spawned up // by this sprite3D and the straight line between the camera and the hit point. sHelperMatrix.copyFrom(transformationMatrix3D); sHelperMatrix.invert(); stage.getCameraPosition(this, sHelperPoint); MatrixUtil.transformCoords3D(sHelperMatrix, localPoint.x, localPoint.y, 0, sHelperPointAlt); MathUtil.intersectLineWithXYPlane(sHelperPoint, sHelperPointAlt, localPoint); return super.hitTest(localPoint); } } public override function setRequiresRedraw():void { var was2D:Boolean = _is2D; _is2D = _z > -E && _z < E && _rotationX > -E && _rotationX < E && _rotationY > -E && _rotationY < E && _pivotZ > -E && _pivotZ < E; if (_is2D != was2D) updateSupportsRenderCache(); super.setRequiresRedraw(); } protected override function get supportsRenderCache():Boolean { return _is2D && super.supportsRenderCache; } // helpers private function onAddedChild(event:Event):void { recursivelySetIs3D(event.target as DisplayObject, true); } private function onRemovedChild(event:Event):void { recursivelySetIs3D(event.target as DisplayObject, false); } private function recursivelySetIs3D(object:DisplayObject, value:Boolean):void { if (object is Sprite3D) return; if (object is DisplayObjectContainer) { var container:DisplayObjectContainer = object as DisplayObjectContainer; var numChildren:int = container.numChildren; for (var i:int=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy