awayjs-display
Version:
AwayJS displaylist classes
273 lines (217 loc) • 6.75 kB
text/typescript
import {Box} from "awayjs-core/lib/geom/Box";
import {Matrix3D} from "awayjs-core/lib/geom/Matrix3D";
import {Sphere} from "awayjs-core/lib/geom/Sphere";
import {Vector3D} from "awayjs-core/lib/geom/Vector3D";
import {AssetBase} from "awayjs-core/lib/library/AssetBase";
import {IAnimator} from "../animators/IAnimator";
import {RenderableEvent} from "../events/RenderableEvent";
import {MaterialBase} from "../materials/MaterialBase";
import {Style} from "../base/Style";
import {StyleEvent} from "../events/StyleEvent";
import {ElementsEvent} from "../events/ElementsEvent";
import {IRenderable} from "../base/IRenderable";
import {Graphics} from "../graphics/Graphics";
import {ElementsBase} from "../graphics/ElementsBase";
import {TriangleElements} from "../graphics/TriangleElements";
import {IPickingCollider} from "../pick/IPickingCollider";
import {PickingCollision} from "../pick/PickingCollision";
/**
* Graphic wraps a Elements as a scene graph instantiation. A Graphic is owned by a Sprite object.
*
*
* @see away.base.ElementsBase
* @see away.entities.Sprite
*
* @class away.base.Graphic
*/
export class Graphic extends AssetBase implements IRenderable
{
public static _available:Array<Graphic> = new Array<Graphic>();
public static assetType:string = "[asset Graphic]";
public _iIndex:number = 0;
private _boxBounds:Box;
private _boxBoundsInvalid:boolean = true;
private _sphereBounds:Sphere;
private _sphereBoundsInvalid = true;
private _style:Style;
private _material:MaterialBase;
private _elements:ElementsBase;
private _onInvalidatePropertiesDelegate:(event:StyleEvent) => void;
private _onInvalidateVerticesDelegate:(event:ElementsEvent) => void;
public count:number;
public offset:number;
public parent:Graphics;
/**
* The Elements object which provides the geometry data for this Graphic.
*/
public get elements():ElementsBase
{
return this._elements;
}
public set elements(value:ElementsBase)
{
if (this._elements == value)
return;
this._elements = value;
this.invalidateElements();
}
/**
*
*/
public get assetType():string
{
return Graphic.assetType;
}
/**
*
*/
public get animator():IAnimator
{
return this.parent.animator;
}
//TODO test shader picking
// public get shaderPickingDetails():boolean
// {
//
// return this.sourceEntity.shaderPickingDetails;
// }
/**
* The material used to render the current TriangleGraphic. If set to null, its parent Sprite's material will be used instead.
*/
public get material():MaterialBase
{
return this._material || this.parent.material;
}
public set material(value:MaterialBase)
{
if (this.material)
this.material.iRemoveOwner(this);
this._material = value;
if (this.material)
this.material.iAddOwner(this);
}
/**
* The style used to render the current TriangleGraphic. If set to null, its parent Sprite's style will be used instead.
*/
public get style():Style
{
return this._style || this.parent.style;
}
public set style(value:Style)
{
if (this._style == value)
return;
if (this._style)
this._style.removeEventListener(StyleEvent.INVALIDATE_PROPERTIES, this._onInvalidatePropertiesDelegate);
this._style = value;
if (this._style)
this._style.addEventListener(StyleEvent.INVALIDATE_PROPERTIES, this._onInvalidatePropertiesDelegate);
this.invalidateSurface();
}
/**
* Creates a new Graphic object
*/
constructor(index:number, parent:Graphics, elements:ElementsBase, material:MaterialBase = null, style:Style = null, count:number = 0, offset:number = 0)
{
super();
this._onInvalidatePropertiesDelegate = (event:StyleEvent) => this._onInvalidateProperties(event);
this._onInvalidateVerticesDelegate = (event:ElementsEvent) => this._onInvalidateVertices(event);
this._iIndex = index;
this.parent = parent;
this.elements = elements;
this.material = material;
this.style = style;
this.count = count;
this.offset = offset;
}
/**
*
*/
public dispose():void
{
super.dispose();
this.parent.removeGraphic(this);
this.parent = null;
Graphic._available.push(this);
}
public invalidate():void
{
super.invalidate();
this._boxBoundsInvalid = true;
this._sphereBoundsInvalid = true;
}
public invalidateElements():void
{
this.dispatchEvent(new RenderableEvent(RenderableEvent.INVALIDATE_ELEMENTS, this));
this._boxBoundsInvalid = true;
this._sphereBoundsInvalid = true;
}
public invalidateSurface():void
{
this.dispatchEvent(new RenderableEvent(RenderableEvent.INVALIDATE_SURFACE, this));
}
public _iGetExplicitMaterial():MaterialBase
{
return this._material;
}
public _iGetExplicitStyle():Style
{
return this._style;
}
private _onInvalidateProperties(event:StyleEvent):void
{
this.invalidateSurface();
}
private _onInvalidateVertices(event:ElementsEvent):void
{
if (event.attributesView != (<TriangleElements> event.target).positions)
return;
this.invalidate();
this.dispatchEvent(event);
}
/**
* //TODO
*
* @param shortestCollisionDistance
* @param findClosest
* @returns {boolean}
*
* @internal
*/
public _iTestCollision(pickingCollision:PickingCollision, pickingCollider:IPickingCollider):boolean
{
return this._elements._iTestCollision(pickingCollider, this.material, pickingCollision, this.count, this.offset)
}
public applyTransformation(transform:Matrix3D):void
{
this._elements.applyTransformation(transform, this.count, this.offset);
}
public hitTestPoint(x:number, y:number, z:number):boolean
{
var box:Box;
//early out for box test
if(!(box = this.getBoxBounds()).contains(x, y, z))
return false;
return this._elements.hitTestPoint(x, y, z, box, this.count, this.offset);
}
public scale(scale:number):void
{
this._elements.scale(scale, this.count, this.offset);
}
public scaleUV(scaleU:number = 1, scaleV:number = 1):void
{
this._elements.scaleUV(scaleU, scaleV, this.count, this.offset);
}
public getBoxBounds():Box
{
if (this._boxBoundsInvalid) {
this._boxBoundsInvalid = false;
this._boxBounds = this._elements.getBoxBounds(this._boxBounds || (this._boxBounds = new Box()), this.count, this.offset);
}
return this._boxBounds;
}
public getSphereBounds(center:Vector3D, target:Sphere = null):Sphere
{
return this._elements.getSphereBounds(center, target, this.count, this.offset);
}
}