/src/away3d/core/stats/Stats.as
http://openflow-as3.googlecode.com/ · ActionScript · 1 lines · 1 code · 0 blank · 0 comment · 0 complexity · e54b160b1af5d18e3e01f08abab686cb MD5 · raw file
- package away3d.core.stats
{
import away3d.cameras.*;
import away3d.containers.*;
import away3d.core.base.*;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.*;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.*;
import flash.system.System;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
import flash.utils.*;
public class Stats extends Sprite
{
private var totalElements:int = 0;
private var meshes:int = 0;
public var scopeMenu:View3D = null;
public var displayMenu:Sprite = null;
public var geomMenu:Sprite = null;
private var lastrender:int;
private var fpsLabel:StaticTextField;
private var titleField:StaticTextField;
private var perfLabel:StaticTextField;
private var ramLabel:StaticTextField;
private var swfframerateLabel:StaticTextField;
private var avfpsLabel:StaticTextField;
private var peakLabel:StaticTextField;
private var faceLabel:StaticTextField;
private var faceRenderLabel:StaticTextField;
private var geomDetailsLabel:TextField;
private var meshLabel:StaticTextField;
private var fpstotal:int = 0;
private var refreshes:int = 0;
private var bestfps:int = 0;
private var lowestfps:int = 999;
private var bar:Sprite;
private var barwidth:int = 0;
private var closebtn:Sprite;
private var cambtn:Sprite;
private var clearbtn:Sprite;
private var geombtn:Sprite;
private var barscale:int = 0;
private var stageframerate:Number;
private var displayState:int;
private var camLabel:TextField;
private var camMenu:Sprite;
private var camProp:Array;
private var rectclose:Rectangle = new Rectangle(228,4,18,17);
private var rectcam:Rectangle = new Rectangle(207,4,18,17);
private var rectclear:Rectangle = new Rectangle(186,4,18,17);
private var rectdetails:Rectangle = new Rectangle(165,4,18,17);
private var geomLastAdded:String;
private var defautTF:TextFormat = new TextFormat("Verdana", 10, 0x000000);
private var defautTFBold:TextFormat = new TextFormat("Verdana", 10, 0x000000, true);
//
private const VERSION:String = "3";
private const REVISION:String = "5.1";
private const APPLICATION_NAME:String = "Away3D.com";
public var sourceURL:String;
private var menu0:ContextMenuItem;
private var menu1:ContextMenuItem;
private var menu2:ContextMenuItem;
public function Stats(scope:View3D, framerate:Number = 0)
{
scopeMenu = scope;
stageframerate = (framerate)? framerate : 30;
displayState = 0;
sourceURL = scope.sourceURL;
tabEnabled = false;
menu0 = new ContextMenuItem("Away3D Project stats", true, true, true);
menu1 = new ContextMenuItem("View Source", true, true, true);
menu2 = new ContextMenuItem(APPLICATION_NAME+"\tv" + VERSION +"."+REVISION, true, true, true);
var scopeMenuContextMenu:ContextMenu = new ContextMenu();
scopeMenuContextMenu = new ContextMenu();
scopeMenuContextMenu.customItems = sourceURL? [menu0, menu1, menu2] : [menu0, menu2];
menu0.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, displayStats);
menu1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, viewSource);
menu2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, visitWebsite);
scopeMenuContextMenu.hideBuiltInItems();
scopeMenu.contextMenu = scopeMenuContextMenu;
}
public function addSourceURL(url:String):void
{
sourceURL = url;
var scopeMenuContextMenu:ContextMenu = new ContextMenu();
scopeMenuContextMenu.customItems = sourceURL? [menu0, menu1, menu2] : [menu0, menu2];
scopeMenu.contextMenu = scopeMenuContextMenu;
}
//Displays stats
public function displayStats(e:ContextMenuEvent=null):void
{
if(!displayMenu){
scopeMenu.statsOpen = true;
generateSprite();
addEventMouse();
//applyShadow();
}
}
//Redirect to site
public function visitWebsite(e:ContextMenuEvent):void
{
var url:String = "http://www.away3d.com";
var request:URLRequest = new URLRequest(url);
try {
navigateToURL(request);
} catch (error:Error) {
}
}
//View Source files
public function viewSource(e:ContextMenuEvent):void
{
var request:URLRequest = new URLRequest(sourceURL);
try {
navigateToURL(request, "_blank");
} catch (error:Error) {
}
}
//Closes stats and cleans up a bit...
private function closeStats():void
{
scopeMenu.statsOpen = false;
displayState = 0;
scopeMenu.removeEventListener(MouseEvent.MOUSE_DOWN, onCheckMouse);
scopeMenu.removeEventListener(MouseEvent.MOUSE_MOVE, updateTips);
scopeMenu.removeChild(displayMenu);
displayMenu = null;
}
//Mouse Events
private function addEventMouse():void
{
scopeMenu.addEventListener(MouseEvent.MOUSE_DOWN, onCheckMouse);
scopeMenu.addEventListener(MouseEvent.MOUSE_MOVE, updateTips);
}
private function updateTips(me:MouseEvent):void
{
if(scopeMenu != null){
var x:Number = displayMenu.mouseX;
var y:Number = displayMenu.mouseY;
var pt:Point = new Point(x,y);
try {
if(rectcam.containsPoint(pt)){
titleField.text = "CAMERA INFO";
} else if(rectclose.containsPoint(pt)){
titleField.text = "CLOSE STATS";
} else if(rectclear.containsPoint(pt)){
titleField.text = "CLEAR AVERAGES";
} else if(rectdetails.containsPoint(pt)){
titleField.text = "MESH INFO";
} else{
titleField.text = "AWAY3D PROJECT";
}
} catch (e:Error) {
}
}
}
private function onCheckMouse(me:MouseEvent):void
{
var x:Number = displayMenu.mouseX;
var y:Number = displayMenu.mouseY;
var pt:Point = new Point(x,y);
if(rectcam.containsPoint(pt)){
if(displayState != 1){
closeOtherScreen(displayState);
displayState = 1;
showCamInfo();
} else{
displayState = 0;
hideCamInfo();
}
} else if(rectdetails.containsPoint(pt)){
if(displayState != 2){
closeOtherScreen(displayState);
displayState = 2;
showGeomInfo();
} else{
displayState = 0;
hideGeomInfo();
}
} else if(rectclose.containsPoint(pt)){
closeStats();
} else if(rectclear.containsPoint(pt)){
clearStats();
} else{
if(displayMenu.mouseY<=20)
{
displayMenu.startDrag();
scopeMenu.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
}
}
}
private function closeOtherScreen(actual:int):void {
switch(actual){
case 1:
hideCamInfo();
break;
case 2:
hideGeomInfo();
}
}
private function mouseReleased(event:MouseEvent):void {
displayMenu.stopDrag();
scopeMenu.removeEventListener(MouseEvent.MOUSE_UP, mouseReleased);
}
//drawing the stats container
private function generateSprite():void
{
displayMenu = new Sprite();
var myMatrix:Matrix = new Matrix();
myMatrix.rotate(90 * Math.PI/180);
displayMenu.graphics.beginGradientFill("linear", [0x333366, 0xCCCCCC], [1,1], [0,255], myMatrix, "pad", "rgb", 0);
displayMenu.graphics.drawRect(0, 0, 250, 86);
displayMenu.graphics.beginFill(0x333366);
displayMenu.graphics.drawRect(3, 3, 244, 20);
scopeMenu.addChild(displayMenu);
displayMenu.x -= displayMenu.width*.5;
displayMenu.y -= displayMenu.height*.5;
// generate closebtn
closebtn = new Sprite();
closebtn.graphics.beginFill(0x666666);
closebtn.graphics.drawRect(0, 0, 18, 17);
var cross:Sprite = new Sprite();
cross.graphics.beginFill(0xC6D0D8);
cross.graphics.drawRect(2, 7, 14, 4);
cross.graphics.endFill();
cross.graphics.beginFill(0xC6D0D8);
cross.graphics.drawRect(7, 2, 4, 14);
cross.graphics.endFill();
cross.rotation = 45;
cross.x+=9;
cross.y-=4;
closebtn.addChild(cross);
displayMenu.addChild(closebtn);
closebtn.x = 228;
closebtn.y = 4;
// generate cam btn
cambtn = new Sprite();
var cam:Graphics = cambtn.graphics;
cam.beginFill(0x666666);
cam.drawRect(0, 0, 18, 17);
cam.endFill();
cam.beginFill(0xC6D0D8);
cam.moveTo(10,8);
cam.lineTo(16,4);
cam.lineTo(16,14);
cam.lineTo(10,10);
cam.lineTo(10,8);
cam.drawRect(2, 6, 8, 6);
cam.endFill();
displayMenu.addChild(cambtn);
cambtn.x = 207;
cambtn.y = 4;
// generate clear btn
clearbtn = new Sprite();
var clear_btn:Graphics = clearbtn.graphics;
clear_btn.beginFill(0x666666);
clear_btn.drawRect(0, 0, 18, 17);
clear_btn.endFill();
clear_btn.beginFill(0xC6D0D8);
clear_btn.drawRect(6, 6, 6, 6);
clear_btn.endFill();
displayMenu.addChild(clearbtn);
clearbtn.x = 186;
clearbtn.y = 4;
// generate geometrie btn
geombtn = new Sprite();
var geom_btn:Graphics = geombtn.graphics;
geom_btn.beginFill(0x666666);
geom_btn.drawRect(0, 0, 18, 17);
geom_btn.endFill();
geom_btn.beginFill(0xC6D0D8, 0.7);
geom_btn.moveTo(3,4);
geom_btn.lineTo(11,2);
geom_btn.lineTo(16,5);
geom_btn.lineTo(7,7);
geom_btn.lineTo(3,4);
geom_btn.beginFill(0x7D8489, 0.8);
geom_btn.moveTo(3,4);
geom_btn.lineTo(7,7);
geom_btn.lineTo(7,16);
geom_btn.lineTo(3,12);
geom_btn.lineTo(3,4);
geom_btn.beginFill(0xC6D0D8,1);
geom_btn.moveTo(7,7);
geom_btn.lineTo(16,5);
geom_btn.lineTo(15,13);
geom_btn.lineTo(7,16);
geom_btn.lineTo(7,7);
geom_btn.endFill();
geom_btn.endFill();
displayMenu.addChild(geombtn);
geombtn.x = 165;
geombtn.y = 4;
// generate bar
displayMenu.graphics.beginGradientFill("linear", [0x000000, 0xFFFFFF], [1,1], [0,255], new Matrix(), "pad", "rgb", 0);
displayMenu.graphics.drawRect(3, 22, 244, 4);
displayMenu.graphics.endFill();
bar = new Sprite();
bar.graphics.beginFill(0xFFFFFF);
bar.graphics.drawRect(0, 0, 244, 4);
displayMenu.addChild(bar);
bar.x = 3;
bar.y = 22;
barwidth = 244;
barscale = int(barwidth/stageframerate);
// displays Away logo
displayPicto();
// Generate textfields
// title
titleField = new StaticTextField("AWAY3D PROJECT", new TextFormat("Verdana", 10, 0xFFFFFF, true));
titleField.height = 20;
titleField.width = 140;
titleField.x = 22;
titleField.y = 4;
displayMenu.addChild(titleField);
// fps
var fpst:StaticTextField = new StaticTextField("FPS:",defautTFBold);
fpsLabel = new StaticTextField();
displayMenu.addChild(fpst);
displayMenu.addChild(fpsLabel);
fpst.x = 3;
fpst.y = fpsLabel.y = 30;
fpsLabel.x = fpst.x+fpst.width-2;
//average perf
var afpst:StaticTextField = new StaticTextField("AFPS:",defautTFBold);
avfpsLabel = new StaticTextField();
displayMenu.addChild(afpst);
displayMenu.addChild(avfpsLabel);
afpst.x = 52;
afpst.y = avfpsLabel.y = fpsLabel.y;
avfpsLabel.x = afpst.x+afpst.width-2;
//Max peak
var peakfps:StaticTextField = new StaticTextField("Max:",defautTFBold);
peakLabel = new StaticTextField();
displayMenu.addChild(peakfps);
displayMenu.addChild(peakLabel);
peakfps.x = 107;
peakfps.y = peakLabel.y = avfpsLabel.y;
peakfps.autoSize = "left";
peakLabel.x = peakfps.x+peakfps.width-2;
//MS
var pfps:StaticTextField = new StaticTextField("MS:",defautTFBold);
perfLabel = new StaticTextField();
perfLabel.defaultTextFormat = defautTF;
displayMenu.addChild(pfps);
displayMenu.addChild(perfLabel);
pfps.x = 177;
pfps.y = perfLabel.y = fpsLabel.y;
pfps.autoSize = "left";
perfLabel.x = pfps.x+pfps.width-2;
//ram usage
var ram:StaticTextField = new StaticTextField("RAM:",defautTFBold);
ramLabel = new StaticTextField();
displayMenu.addChild(ram);
displayMenu.addChild(ramLabel);
ram.x = 3;
ram.y = ramLabel.y = 46;
ram.autoSize = "left";
ramLabel.x = ram.x+ram.width-2;
//meshes count
var meshc:StaticTextField = new StaticTextField("MESHES:",defautTFBold);
meshLabel = new StaticTextField();
displayMenu.addChild(meshc);
displayMenu.addChild(meshLabel);
meshc.x = 90;
meshc.y = meshLabel.y = ramLabel.y;
meshc.autoSize = "left";
meshLabel.x = meshc.x+meshc.width-2;
//swf framerate
var rate:StaticTextField = new StaticTextField("SWF FR:",defautTFBold);
swfframerateLabel = new StaticTextField();
displayMenu.addChild(rate);
displayMenu.addChild(swfframerateLabel);
rate.x = 170;
rate.y = swfframerateLabel.y = ramLabel.y;
rate.autoSize = "left";
swfframerateLabel.x = rate.x+rate.width-2;
//faces
var faces:StaticTextField = new StaticTextField("T ELEMENTS:",defautTFBold);
faceLabel = new StaticTextField();
displayMenu.addChild(faces);
displayMenu.addChild(faceLabel);
faces.x = 3;
faces.y = faceLabel.y = 62;
faces.autoSize = "left";
faceLabel.x = faces.x+faces.width-2;
//shown faces
var facesrender:StaticTextField = new StaticTextField("R ELEMENTS:",defautTFBold);
faceRenderLabel = new StaticTextField();
displayMenu.addChild(facesrender);
displayMenu.addChild(faceRenderLabel);
facesrender.x = 115;
facesrender.y = faceRenderLabel.y = faceLabel.y;
facesrender.autoSize = "left";
faceRenderLabel.x = facesrender.x+facesrender.width-2;
}
public function updateStats(renderedfaces:int, camera:Camera3D):void
{
var now:int = getTimer();
var perf:int = now - lastrender;
lastrender = now;
if (perf < 1000) {
var fps:int = int(1000 / (perf+0.001));
fpstotal += fps;
refreshes ++;
var average:int = fpstotal/refreshes;
bestfps = (fps>bestfps)? fps : bestfps;
lowestfps = (fps<lowestfps)? fps : lowestfps;
var w:int = barscale*fps;
bar.width = (w<=barwidth)? w : barwidth;
}
//color
var procent:int = (bar.width/barwidth)*100;
var colorTransform:ColorTransform = bar.transform.colorTransform;
colorTransform.color = 255-(2.55*procent) << 16 | 2.55*procent << 8 | 40;
bar.transform.colorTransform = colorTransform;
if(displayState == 0){
avfpsLabel.text = ""+average;
ramLabel.text = ""+int(System.totalMemory/1024/102.4)/10+"MB";
peakLabel.text = lowestfps+"/"+bestfps;
fpsLabel.text = "" + fps;
perfLabel.text = "" + perf;
faceLabel.text = ""+totalElements;
faceRenderLabel.text = ""+renderedfaces;
meshLabel.text = ""+meshes;
swfframerateLabel.text = ""+stageframerate;
} else if(displayState == 1){
var caminfo:String = "";
var _length:int = camProp.length;
for(var i:int = 0;i<_length;++i){
try{
if(i>12){
caminfo += String(camera[camProp[i]])+"\n";
} else {
var info:String = String(camera[camProp[i]]);
caminfo += info.substring(0, 19)+"\n";
}
} catch(e:Error){
caminfo += "\n";
}
}
camLabel.text = caminfo;
} else if(displayState == 2){
geomDetailsLabel.text = stats;
//geomDetailsLabel.scrollV = geomDetailsLabel.maxScrollV;
}
}
//clear peaks
private function clearStats():void
{
fpstotal = 0;
refreshes = 0;
bestfps = 0;
lowestfps = 999;
}
//geometrie info
private function showGeomInfo():void
{
if(geomMenu == null){
createGeometryMenu();
} else{
displayMenu.addChild(geomMenu);
geomMenu.y = 26;
}
}
private function hideGeomInfo():void
{
if(geomMenu != null){
displayMenu.removeChild(geomMenu);
}
}
private function createGeometryMenu():void{
geomMenu = new Sprite();
var myMatrix:Matrix = new Matrix();
myMatrix.rotate(90 * Math.PI/180);
geomMenu.graphics.beginGradientFill("linear", [0x333366, 0xCCCCCC], [1,1], [0,255], myMatrix, "pad", "rgb", 0);
geomMenu.graphics.drawRect(0, 0, 250, 200);
displayMenu.addChild(geomMenu);
geomMenu.y = 26;
geomDetailsLabel = new TextField();
geomDetailsLabel.x = 3;
geomDetailsLabel.y = 3;
geomDetailsLabel.defaultTextFormat = defautTF;
geomDetailsLabel.text = stats;
geomDetailsLabel.height = 200;
geomDetailsLabel.width = 235;
geomDetailsLabel.multiline = true;
geomDetailsLabel.selectable = true;
geomDetailsLabel.wordWrap = true;
geomMenu.addChild(geomDetailsLabel);
}
//cam info
private function showCamInfo():void
{
if(camMenu == null){
createCamMenu();
} else{
displayMenu.addChild(camMenu);
camMenu.y = 26;
}
}
private function hideCamInfo():void
{
if(camMenu != null){
displayMenu.removeChild(camMenu);
}
}
// cam info menu
private function createCamMenu():void
{
camMenu = new Sprite();
var myMatrix:Matrix = new Matrix();
myMatrix.rotate(90 * Math.PI/180);
camMenu.graphics.beginGradientFill("linear", [0x333366, 0xCCCCCC], [1,1], [0,255], myMatrix, "pad", "rgb", 0);
camMenu.graphics.drawRect(0, 0, 250, 220);
displayMenu.addChild(camMenu);
camMenu.y = 26;
camLabel = new TextField();
camLabel.height = 210;
camLabel.width = 170;
camLabel.multiline = true;
camLabel.selectable = false;
var tf:TextFormat = defautTF;
tf.leading = 1.5;
camLabel.defaultTextFormat = tf;
camLabel.wordWrap = true;
camMenu.addChild(camLabel);
camLabel.x = 100;
camLabel.y = 3;
camProp = ["x","y","z","rotationX", "rotationY", "rotationZ", "zoom","focus","distance","panAngle","tiltAngle","minTiltAngle","maxTiltAngle","steps","yfactor"];
//props
var campropfield:TextField = new TextField();
tf = new TextFormat("Verdana", 10, 0x000000, true);
tf.leading = 1.5;
tf.align = "right";
campropfield.defaultTextFormat = tf;
campropfield.x = campropfield.y = 3;
campropfield.multiline = true;
campropfield.selectable = false;
campropfield.autoSize = "left";
campropfield.height = 210;
var _length:int = camProp.length;
for(var i:int = 0;i<_length;++i){
campropfield.appendText(camProp[i]+":\n");
}
camMenu.addChild(campropfield);
}
private function displayPicto():void
{
var logoShape:Shape = new Logo();
displayMenu.addChild(logoShape);
logoShape.x = logoShape.y = 4;
}
internal var type:String;
internal var elementcount:int;
internal var url:String;
public var stats:String = "";
public function clearObjects():void
{
stats = "";
totalElements = 0;
meshes = 0;
geomLastAdded = "";
}
// registration faces and types
public function addObject(node:Mesh):void
{
type = node.type;
elementcount = node.elements.length;
url = node.url;
if (type != null && elementcount != 0) {
stats += " - " + type + " , elements: " + elementcount + ", url: " + url + "\n";
geomLastAdded = " - " + type + " , elements: " + elementcount + ", url: " + url + "\n";
totalElements += elementcount;
meshes += 1;
} else {
stats += " - " + type + " , url: " + url + "\n";
geomLastAdded = " - " + type + " , url: " + url + "\n";
}
}
//TODO: generateClipBoardInfo not implemented yet
/*
private function generateClipBoardInfo():void{
var strReport:String = "-- AWAY3D STATS REPORT --\n\n";
strReport+= "GEOMETRY:\n";
strReport+= stats ;
strReport+= "\nCAMERA:\n";
var camera:Camera3D = scopeMenu.camera;
//System.setClipboard(strReport);
}
*/
}
}