PageRenderTime 61ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/src/com/panosalado/view/Panorama.as

http://github.com/mstandio/SaladoPlayer
ActionScript | 1055 lines | 784 code | 99 blank | 172 comment | 136 complexity | 323849475a821f43f2f6a37c34ca2adc MD5 | raw file
Possible License(s): LGPL-3.0
  1. /*
  2. Copyright 2010 Zephyr Renner.
  3. This file is part of PanoSalado.
  4. PanoSalado is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. PanoSalado is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with PanoSalado. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package com.panosalado.view
  16. {
  17. //import performance.profiler.*;
  18. import com.panosalado.model.QuadTreeCube;
  19. //import com.panosalado.controller.ICamera;
  20. //import com.panosalado.controller.IResizer;
  21. import com.panosalado.model.Characteristics;
  22. import com.panosalado.model.Tile;
  23. import com.panosalado.model.TilePyramid;
  24. import com.panosalado.model.Capicua;
  25. import com.panosalado.model.ViewData;
  26. //import com.panosalado.events.ReadyEvent;
  27. //import com.panosalado.events.ViewEvent;
  28. import com.panosalado.loading.LoadingStatistics;
  29. import com.panosalado.loading.TileLoader;
  30. import com.panosalado.loading.IOErrorEventHandler;
  31. import com.panosalado.core.PanoSalado;
  32. import flash.display.BlendMode;
  33. import flash.display.Bitmap;
  34. import flash.display.DisplayObject;
  35. import flash.display.Graphics;
  36. import flash.display.GraphicsBitmapFill;
  37. import flash.display.IGraphicsData;
  38. import flash.display.Loader;
  39. import flash.display.LoaderInfo;
  40. import flash.display.Sprite;
  41. import flash.events.Event;
  42. import flash.events.IOErrorEvent;
  43. import flash.events.TimerEvent;
  44. import flash.geom.Matrix3D;
  45. import flash.geom.PerspectiveProjection;
  46. import flash.geom.Point;
  47. import flash.geom.Rectangle;
  48. import flash.geom.Utils3D;
  49. import flash.geom.Vector3D;
  50. import flash.net.URLRequest;
  51. import flash.text.TextSnapshot;
  52. import flash.utils.Dictionary;
  53. import flash.utils.getTimer;
  54. import flash.utils.Timer;
  55. import flash.display.BitmapData;
  56. import flash.display.GraphicsStroke;
  57. import flash.display.GraphicsSolidFill;
  58. //import performance.profiler.*;
  59. final public class Panorama
  60. {
  61. protected var _graphicsData:Vector.<IGraphicsData>;
  62. protected var _tiltAroundAxis:Vector3D;
  63. protected var _displayingTile:Tile;
  64. protected var _panRawData:Vector.<Number>;
  65. protected var _tiltRawData:Vector.<Number>;
  66. protected var _transformRawData:Vector.<Number>;
  67. protected var _tempClippedVertices:Vector.<Number>;
  68. protected var _tempClippedUvtData:Vector.<Number>;
  69. protected var _tempPoint:Vector3D;
  70. protected var _referenceTransformedVertices:Vector.<Number>;
  71. protected var _capicua:Capicua;
  72. protected var _loadingStatistics:LoadingStatistics;
  73. public var dispatchEvents:Boolean;
  74. private var __loaders:Vector.<TileLoader> = new Vector.<TileLoader>();
  75. private var __urlRequest:URLRequest = new URLRequest();
  76. private var __toRadians:Number = Math.PI / 180;
  77. private var __toDegrees:Number = 180 / Math.PI;
  78. private var __pi1_2:Number = Math.PI / 2;
  79. private static const INSIDE:uint = 0;
  80. private static const OUTSIDE:uint = 1;
  81. private static const OUT_IN:uint = 2;
  82. private static const IN_OUT:uint = 3;
  83. private static var __instance:Panorama;
  84. public function Panorama() {
  85. if (__instance != null) throw new Error("Panorama is a singleton class; please access the single instance with Panorama.instance.");
  86. _graphicsData = new Vector.<IGraphicsData>();
  87. _tiltAroundAxis = new Vector3D(0,0,0);
  88. _panRawData = new Vector.<Number>(16,true);
  89. _tiltRawData = new Vector.<Number>(16,true);
  90. _transformRawData = new Vector.<Number>(16,true);
  91. _tempClippedVertices = new Vector.<Number>();
  92. _tempClippedUvtData = new Vector.<Number>();
  93. _tempPoint = new Vector3D();
  94. _referenceTransformedVertices = new Vector.<Number>();
  95. _capicua = new Capicua();
  96. _loadingStatistics = LoadingStatistics.instance;
  97. dispatchEvents = true;
  98. }
  99. public static function get instance():Panorama {
  100. if (__instance == null) __instance = new Panorama();
  101. return __instance;
  102. }
  103. public function processDependency(reference:Object,characteristics:*):void {
  104. if (characteristics == Characteristics.VIEW_DATA) {
  105. if (reference.hasOwnProperty("renderFunction"))
  106. (reference as PanoSalado).renderFunction = render;
  107. }
  108. }
  109. final public function render( viewData:ViewData, targetGraphics:Graphics = null):Boolean
  110. {
  111. //if (targetGraphics) Profiler.instance.beginProfiling();
  112. //if (targetGraphics) Profiler.instance.begin("render");
  113. //viewData vars. fetch them once since they are getter functions
  114. var pan:Number = -viewData._pan;
  115. var tilt:Number = viewData._tilt;
  116. var fieldOfView:Number = viewData._fieldOfView;
  117. var boundsWidth:Number = viewData._boundsWidth;
  118. var boundsHeight:Number = viewData._boundsHeight;
  119. var tierThreshold:Number = viewData._tierThreshold;
  120. var perspective:Matrix3D = viewData.perspectiveMatrix3D;
  121. var transform:Matrix3D = viewData.transformMatrix3D;
  122. var perspectiveProjection:PerspectiveProjection = viewData.perspectiveProjection;
  123. var frustumLeft:Vector3D = viewData.frustumLeft;
  124. var frustumRight:Vector3D = viewData.frustumRight;
  125. var frustumTop:Vector3D = viewData.frustumTop;
  126. var frustumBottom:Vector3D = viewData.frustumBottom;
  127. var pixelsPerDegree:Number = viewData.pixelsPerDegree;
  128. var tile:Tile = viewData._tile as Tile;
  129. var rootTile:QuadTreeCube = viewData._tile as QuadTreeCube;
  130. var displayingTile:Tile = rootTile.displayingTile;
  131. //variables used across blocks. no need to have multiple vars for the same functions in different blocks.
  132. var referenceUvtData:Vector.<Number>;
  133. var workingUvtData:Vector.<Number>;
  134. var workingIndices:Vector.<int>;
  135. var i:int;
  136. var len:int;
  137. var transformedVertices:Vector.<Number>;
  138. var referenceTransformedVertices:Vector.<Number>;
  139. /* clear list of displaying tiles, IF being called with a render event (result of Stage.invalidate() */
  140. if (targetGraphics)
  141. { //function is being called as a result of Stage.invalidate();
  142. // loop linked list of displaying tiles setting displaying to false.
  143. while (displayingTile != null){
  144. var nextDisplayingTile:Tile = displayingTile.nextDisplayingTile;
  145. displayingTile.displaying = false;
  146. displayingTile.nextDisplayingTile = null;
  147. displayingTile = nextDisplayingTile;
  148. }
  149. _graphicsData.length = 0;
  150. var graphicsDataIndex:int = 0;
  151. }
  152. /* update transform matrix because pan or tilt is invalid. API standard functions have been inlined */
  153. if (viewData.invalidTransform){
  154. var panRadians:Number = pan * __toRadians;
  155. var panPlus90Radians:Number = panRadians + __pi1_2;
  156. _tiltAroundAxis.x = Math.sin( -panPlus90Radians );
  157. _tiltAroundAxis.z = Math.cos( -panPlus90Radians );
  158. var vTilt:Vector.<Number>,
  159. vPan:Vector.<Number>,
  160. vTransform:Vector.<Number>,
  161. sinW2:Number,
  162. x:Number,
  163. y:Number,
  164. z:Number,
  165. w:Number,
  166. tiltRadians:Number;
  167. tiltRadians = tilt * __toRadians;
  168. /* inlined: tilt.rawData = prependRotation( _tiltAroundAxis, viewData._tilt * __toRadians ); 
  169. nota bene: Matrix3D.prependRotation is relative, while prependRotation is ABSOLUTE, which is important
  170. because we know that this function can be called multiple times in a frame to predict and load future needed tiles.
  171. */
  172. vTilt=_tiltRawData;
  173. sinW2 = Math.sin(tiltRadians*0.5);
  174. x = _tiltAroundAxis.x * sinW2;
  175. y = _tiltAroundAxis.y * sinW2;
  176. z = _tiltAroundAxis.z * sinW2;
  177. w = Math.cos(tiltRadians*0.5);
  178. vTilt[0] = (1-2*y*y-2*z*z);
  179. vTilt[1] = (2*x*y+2*w*z);
  180. vTilt[2] = (2*x*z-2*w*y);
  181. vTilt[3]=0;
  182. vTilt[4] = (2*x*y-2*w*z);
  183. vTilt[5] = (1-2*x*x-2*z*z);
  184. vTilt[6] = (2*y*z+2*w*x);
  185. vTilt[7]=0;
  186. vTilt[8] = (2*x*z+2*w*y);
  187. vTilt[9] = (2*y*z-2*w*x);
  188. vTilt[10] = (1-2*x*x-2*y*y);
  189. vTilt[11]=0;
  190. vTilt[12]=0; //translation X
  191. vTilt[13]=0; //translation Y
  192. vTilt[14]=0; //translation Z
  193. vTilt[15]=1;
  194. //inlined pan.rawData = prependRotation( Vector3D.Y_AXIS, viewData._pan * __toRadians ); see above note
  195. vPan=_panRawData;
  196. sinW2 = Math.sin(panRadians*0.5);
  197. x = 0;
  198. y = sinW2;
  199. z = 0;
  200. w = Math.cos(panRadians*0.5);
  201. vPan[0] = (1-2*y*y-2*z*z);
  202. vPan[1] = (2*x*y+2*w*z);
  203. vPan[2] = (2*x*z-2*w*y);
  204. vPan[3]=0;
  205. vPan[4] = (2*x*y-2*w*z);
  206. vPan[5] = (1-2*x*x-2*z*z);
  207. vPan[6] = (2*y*z+2*w*x);
  208. vPan[7]=0;
  209. vPan[8] = (2*x*z+2*w*y);
  210. vPan[9] = (2*y*z-2*w*x);
  211. vPan[10] = (1-2*x*x-2*y*y);
  212. vPan[11]=0;
  213. vPan[12]=0; //translation X
  214. vPan[13]=0; //translation Y
  215. vPan[14]=0; //translation Z
  216. vPan[15]=1;
  217. //pan = matrix3DMultiply(tilt, pan);
  218. vTransform = _transformRawData;
  219. vTransform[0] = vTilt[0] * vPan[0] + vTilt[1] * vPan[4] + vTilt[2] * vPan[8];
  220. vTransform[1] = vTilt[0] * vPan[1] + vTilt[1] * vPan[5] + vTilt[2] * vPan[9];
  221. vTransform[2] = vTilt[0] * vPan[2] + vTilt[1] * vPan[6] + vTilt[2] * vPan[10];
  222. vTransform[3] = vTilt[0] * vPan[3] + vTilt[1] * vPan[7] + vTilt[2] * vPan[11] + vTilt[3];
  223. vTransform[4] = vTilt[4] * vPan[0] + vTilt[5] * vPan[4] + vTilt[6] * vPan[8];
  224. vTransform[5] = vTilt[4] * vPan[1] + vTilt[5] * vPan[5] + vTilt[6] * vPan[9];
  225. vTransform[6] = vTilt[4] * vPan[2] + vTilt[5] * vPan[6] + vTilt[6] * vPan[10];
  226. vTransform[7] = vTilt[4] * vPan[3] + vTilt[5] * vPan[7] + vTilt[6] * vPan[11] + vTilt[7];
  227. vTransform[8] = vTilt[8] * vPan[0] + vTilt[9] * vPan[4] + vTilt[10] * vPan[8];
  228. vTransform[9] = vTilt[8] * vPan[1] + vTilt[9] * vPan[5] + vTilt[10] * vPan[9];
  229. vTransform[10] = vTilt[8] * vPan[2] + vTilt[9] * vPan[6] + vTilt[10] * vPan[10];
  230. vTransform[11] = vTilt[8] * vPan[3] + vTilt[9] * vPan[7] + vTilt[10] * vPan[11] + vTilt[11];
  231. vTransform[12] = 0
  232. vTransform[13] = 0
  233. vTransform[14] = 0
  234. vTransform[15] = 1
  235. transform.rawData = vTransform;
  236. }
  237. /* field of view or view bounds have changed and need to update frustum, as well as pixels per degree of the view area. */
  238. if (viewData.invalidPerspective
  239. ){
  240. //TODO: modify this to use the projectionCenter.
  241. var hFOV1_2:Number = fieldOfView * 0.5 * __toRadians;
  242. var boundsDiagonal:Number = Math.sqrt(boundsWidth * boundsWidth + boundsHeight * boundsHeight);
  243. var adjacent:Number = (boundsWidth * 0.5) / Math.tan( hFOV1_2 );
  244. var vFOV1_2:Number = Math.atan( (boundsHeight * 0.5) / adjacent );
  245. var dFOV:Number = Math.atan( (boundsDiagonal * 0.5) / adjacent ) * 2 * __toDegrees;
  246. pixelsPerDegree = viewData.pixelsPerDegree = (boundsDiagonal / dFOV) / tierThreshold;
  247. //init frustum
  248. var sinH:Number = Math.sin( hFOV1_2 );
  249. var cosH:Number = Math.cos( hFOV1_2 );
  250. var sinV:Number = Math.sin( vFOV1_2 );
  251. var cosV:Number = Math.cos( vFOV1_2 );
  252. //frustum planes are stored as normal (x,y,z) and distance from origin (w)
  253. // x y z w
  254. frustumLeft.x = cosH; /*0*/ frustumLeft.z = sinH; /*0*/ //left plane
  255. frustumRight.x = -cosH; /*0*/ frustumRight.z = sinH; /*0*/ //right plane
  256. /*0*/ frustumTop.y = cosV; frustumTop.z = sinV; /*0*/ //top plane
  257. /*0*/ frustumBottom.y = -cosV; frustumBottom.z = sinV; /*0*/ //bottom plane
  258. perspectiveProjection.focalLength = isNaN(adjacent) ? 0.000001 : adjacent; // COREMOD
  259. perspective = viewData.perspectiveMatrix3D = perspectiveProjection.toMatrix3D(); // NB: toMatrix3D returns a NEW object so must copy it back to _perspective too.
  260. /* Flash bug: with stage.scaleMode = StageScaleMode.NO_RESIZE setting
  261. perspectiveProjection.fieldOfView does not update focalLength, BUT setting focalLength
  262. does update fieldOfView. One workaround is to scale the resulting matrix from
  263. perspectiveProjection.toMatrix3D(), but the projection then will not correctly project
  264. native DisplayObjects. Setting perspectiveProjection.focalLength solves the problem.
  265. _projection.fieldOfView = fieldOfView;
  266. perspective = _perspective = _projection.toMatrix3D();
  267. // scale / 1 = boundsWidth / 500 NB: 500 is the default stage width
  268. var scale:Number = boundsWidth/500;
  269. perspective.appendScale( scale, scale, scale );
  270. */
  271. }
  272. // determine which tiles to render (loop through quadtree)
  273. var capicua:Capicua = _capicua;
  274. // re-initialize capicua
  275. capicua.cap = tile;
  276. capicua.cua = null;
  277. selectTiles: while(tile = capicua.cap)
  278. {
  279. capicua.cap = capicua.cap.next;
  280. //Profiler.instance.begin("clip");
  281. clipVerticesBlock: {
  282. transformedVertices = tile.transformedVertices;
  283. transformedVertices.length = 0;
  284. transform.transformVectors(tile.vertices, // in
  285. transformedVertices); // out
  286. //unclipped vertices will be needed for generating preview uvtData, so store them here.
  287. if (!tile.graphicsBitmapFill.bitmapData) {
  288. referenceTransformedVertices = _referenceTransformedVertices
  289. len = transformedVertices.length;
  290. referenceTransformedVertices.length = 0;
  291. for (i = 0; i < len; i++){ referenceTransformedVertices[i] = transformedVertices[i]; }
  292. }
  293. var tileInView:Boolean = true;
  294. referenceUvtData = (tile.previewUvtData.length == 0) ? tile.uvtData : tile.previewUvtData;
  295. workingUvtData = tile.clippedUvtData;
  296. workingIndices = tile.clippedIndices;
  297. // copy referenceUvtData
  298. len = referenceUvtData.length;
  299. workingUvtData.length = 0;
  300. for (i = 0; i < len; i++){ workingUvtData[i] = referenceUvtData[i] }
  301. //clip to each of the "side" planes, if there are no output transformedVertices, tile is out
  302. var dist1:Number;
  303. var vertexIndex:int;
  304. var uvtIndex:int;
  305. var pt0X:Number;
  306. var pt0Y:Number;
  307. var pt0Z:Number;
  308. var uv0U:Number;
  309. var uv0V:Number;
  310. var ii:int;
  311. var pt1X:Number;
  312. var pt1Y:Number;
  313. var pt1Z:Number;
  314. var uv1U:Number;
  315. var uv1V:Number;
  316. var dist2:Number;
  317. var d:Number;
  318. var status:uint;
  319. //clipToFrustumPlane( transformedVertices, workingUvtData, frustumTop );
  320. clipToFrustumTop: {
  321. dist1 = transformedVertices[0] * frustumTop.x + transformedVertices[1] * frustumTop.y + transformedVertices[2] * frustumTop.z;
  322. vertexIndex = 0;
  323. uvtIndex = 0;
  324. _tempClippedVertices.length = 0;
  325. _tempClippedUvtData.length = 0;
  326. len = int(transformedVertices.length / 3);
  327. i = 0;
  328. clipLoopTop: while(i < len)
  329. {
  330. pt0X = transformedVertices[int(i*3)];
  331. pt0Y = transformedVertices[int(i*3+1)];
  332. pt0Z = transformedVertices[int(i*3+2)];
  333. uv0U = workingUvtData[int(i*3)];
  334. uv0V = workingUvtData[int(i*3+1)];
  335. ii = (i+1 < len) ? i+1 : 0;
  336. pt1X = transformedVertices[int((ii)*3)];
  337. pt1Y = transformedVertices[int((ii)*3+1)];
  338. pt1Z = transformedVertices[int((ii)*3+2)];
  339. uv1U = workingUvtData[int(ii*3)];
  340. uv1V = workingUvtData[int(ii*3+1)];
  341. dist2 = pt1X * frustumTop.x + pt1Y * frustumTop.y + pt1Z * frustumTop.z;
  342. d = dist1 / (dist1-dist2);
  343. if (isNaN(d)) d = 1; // !important, above can give divide by 0 errors.
  344. if( dist1 < 0 && dist2 < 0 ) status = OUTSIDE;
  345. else if( dist1 > 0 && dist2 > 0 ) status = INSIDE;
  346. else if( dist1 > 0 && dist2 < 0 ) status = IN_OUT;
  347. else status = OUT_IN;
  348. switch( status )
  349. {
  350. case INSIDE:
  351. _tempClippedVertices[vertexIndex++] = pt1X;
  352. _tempClippedVertices[vertexIndex++] = pt1Y;
  353. _tempClippedVertices[vertexIndex++] = pt1Z;
  354. _tempClippedUvtData[uvtIndex++] = uv1U;
  355. _tempClippedUvtData[uvtIndex++] = uv1V;
  356. _tempClippedUvtData[uvtIndex++] = 1;
  357. break;
  358. case IN_OUT:
  359. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  360. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  361. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  362. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  363. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  364. _tempClippedUvtData[uvtIndex++] = 1;
  365. break;
  366. case OUT_IN:
  367. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  368. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  369. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  370. _tempClippedVertices[vertexIndex++] = pt1X;
  371. _tempClippedVertices[vertexIndex++] = pt1Y;
  372. _tempClippedVertices[vertexIndex++] = pt1Z;
  373. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  374. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  375. _tempClippedUvtData[uvtIndex++] = 1;
  376. _tempClippedUvtData[uvtIndex++] = uv1U;
  377. _tempClippedUvtData[uvtIndex++] = uv1V;
  378. _tempClippedUvtData[uvtIndex++] = 1;
  379. break;
  380. default:
  381. break;
  382. }
  383. dist1 = dist2;
  384. i++;
  385. }
  386. transformedVertices.length = workingUvtData.length = 0;
  387. len = _tempClippedVertices.length;
  388. for (i=0; i<len; i++) transformedVertices[i] = _tempClippedVertices[i];
  389. for (i=0; i<len; i++) workingUvtData[i] = _tempClippedUvtData[i];
  390. }
  391. if (transformedVertices.length == 0) {
  392. tileInView = false; break clipVerticesBlock;
  393. }
  394. //clipToFrustumPlane( transformedVertices, workingUvtData, frustumRight );
  395. clipToFrustumRight: {
  396. dist1 = transformedVertices[0] * frustumRight.x + transformedVertices[1] * frustumRight.y + transformedVertices[2] * frustumRight.z;
  397. vertexIndex = 0;
  398. uvtIndex = 0;
  399. _tempClippedVertices.length = 0;
  400. _tempClippedUvtData.length = 0;
  401. len = int(transformedVertices.length / 3);
  402. i = 0;
  403. clipLoopRight: while(i < len)
  404. {
  405. pt0X = transformedVertices[int(i*3)];
  406. pt0Y = transformedVertices[int(i*3+1)];
  407. pt0Z = transformedVertices[int(i*3+2)];
  408. uv0U = workingUvtData[int(i*3)];
  409. uv0V = workingUvtData[int(i*3+1)];
  410. ii = (i+1 < len) ? i+1 : 0;
  411. pt1X = transformedVertices[int((ii)*3)];
  412. pt1Y = transformedVertices[int((ii)*3+1)];
  413. pt1Z = transformedVertices[int((ii)*3+2)];
  414. uv1U = workingUvtData[int(ii*3)];
  415. uv1V = workingUvtData[int(ii*3+1)];
  416. dist2 = pt1X * frustumRight.x + pt1Y * frustumRight.y + pt1Z * frustumRight.z;
  417. d = dist1 / (dist1-dist2);
  418. if (isNaN(d)) d = 1; // !important, above can give divide by 0 errors.
  419. if( dist1 < 0 && dist2 < 0 ) status = OUTSIDE;
  420. else if( dist1 > 0 && dist2 > 0 ) status = INSIDE;
  421. else if( dist1 > 0 && dist2 < 0 ) status = IN_OUT;
  422. else status = OUT_IN;
  423. switch( status )
  424. {
  425. case INSIDE:
  426. _tempClippedVertices[vertexIndex++] = pt1X;
  427. _tempClippedVertices[vertexIndex++] = pt1Y;
  428. _tempClippedVertices[vertexIndex++] = pt1Z;
  429. _tempClippedUvtData[uvtIndex++] = uv1U;
  430. _tempClippedUvtData[uvtIndex++] = uv1V;
  431. _tempClippedUvtData[uvtIndex++] = 1;
  432. break;
  433. case IN_OUT:
  434. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  435. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  436. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  437. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  438. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  439. _tempClippedUvtData[uvtIndex++] = 1;
  440. break;
  441. case OUT_IN:
  442. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  443. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  444. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  445. _tempClippedVertices[vertexIndex++] = pt1X;
  446. _tempClippedVertices[vertexIndex++] = pt1Y;
  447. _tempClippedVertices[vertexIndex++] = pt1Z;
  448. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  449. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  450. _tempClippedUvtData[uvtIndex++] = 1;
  451. _tempClippedUvtData[uvtIndex++] = uv1U;
  452. _tempClippedUvtData[uvtIndex++] = uv1V;
  453. _tempClippedUvtData[uvtIndex++] = 1;
  454. break;
  455. default:
  456. break;
  457. }
  458. dist1 = dist2;
  459. i++;
  460. }
  461. transformedVertices.length = workingUvtData.length = 0;
  462. len = _tempClippedVertices.length;
  463. for (i=0; i<len; i++) transformedVertices[i] = _tempClippedVertices[i];
  464. for (i=0; i<len; i++) workingUvtData[i] = _tempClippedUvtData[i];
  465. }
  466. if (transformedVertices.length == 0) {
  467. tileInView = false; break clipVerticesBlock;
  468. }
  469. //clipToFrustumPlane( transformedVertices, workingUvtData, frustumBottom);
  470. clipToFrustumBottom: {
  471. dist1 = transformedVertices[0] * frustumBottom.x + transformedVertices[1] * frustumBottom.y + transformedVertices[2] * frustumBottom.z;
  472. vertexIndex = 0;
  473. uvtIndex = 0;
  474. _tempClippedVertices.length = 0;
  475. _tempClippedUvtData.length = 0;
  476. len = int(transformedVertices.length / 3);
  477. i = 0;
  478. clipLoopBottom: while(i < len)
  479. {
  480. pt0X = transformedVertices[int(i*3)];
  481. pt0Y = transformedVertices[int(i*3+1)];
  482. pt0Z = transformedVertices[int(i*3+2)];
  483. uv0U = workingUvtData[int(i*3)];
  484. uv0V = workingUvtData[int(i*3+1)];
  485. ii = (i+1 < len) ? i+1 : 0;
  486. pt1X = transformedVertices[int((ii)*3)];
  487. pt1Y = transformedVertices[int((ii)*3+1)];
  488. pt1Z = transformedVertices[int((ii)*3+2)];
  489. uv1U = workingUvtData[int(ii*3)];
  490. uv1V = workingUvtData[int(ii*3+1)];
  491. dist2 = pt1X * frustumBottom.x + pt1Y * frustumBottom.y + pt1Z * frustumBottom.z;
  492. d = dist1 / (dist1-dist2);
  493. if (isNaN(d)) d = 1; // !important, above can give divide by 0 errors.
  494. if( dist1 < 0 && dist2 < 0 ) status = OUTSIDE;
  495. else if( dist1 > 0 && dist2 > 0 ) status = INSIDE;
  496. else if( dist1 > 0 && dist2 < 0 ) status = IN_OUT;
  497. else status = OUT_IN;
  498. switch( status )
  499. {
  500. case INSIDE:
  501. _tempClippedVertices[vertexIndex++] = pt1X;
  502. _tempClippedVertices[vertexIndex++] = pt1Y;
  503. _tempClippedVertices[vertexIndex++] = pt1Z;
  504. _tempClippedUvtData[uvtIndex++] = uv1U;
  505. _tempClippedUvtData[uvtIndex++] = uv1V;
  506. _tempClippedUvtData[uvtIndex++] = 1;
  507. break;
  508. case IN_OUT:
  509. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  510. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  511. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  512. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  513. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  514. _tempClippedUvtData[uvtIndex++] = 1;
  515. break;
  516. case OUT_IN:
  517. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  518. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  519. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  520. _tempClippedVertices[vertexIndex++] = pt1X;
  521. _tempClippedVertices[vertexIndex++] = pt1Y;
  522. _tempClippedVertices[vertexIndex++] = pt1Z;
  523. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  524. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  525. _tempClippedUvtData[uvtIndex++] = 1;
  526. _tempClippedUvtData[uvtIndex++] = uv1U;
  527. _tempClippedUvtData[uvtIndex++] = uv1V;
  528. _tempClippedUvtData[uvtIndex++] = 1;
  529. break;
  530. default:
  531. break;
  532. }
  533. dist1 = dist2;
  534. i++;
  535. }
  536. transformedVertices.length = workingUvtData.length = 0;
  537. len = _tempClippedVertices.length;
  538. for (i=0; i<len; i++) transformedVertices[i] = _tempClippedVertices[i];
  539. for (i=0; i<len; i++) workingUvtData[i] = _tempClippedUvtData[i];
  540. }
  541. if (transformedVertices.length == 0) {
  542. tileInView = false; break clipVerticesBlock;
  543. }
  544. //clipToFrustumPlane( transformedVertices, workingUvtData, frustumLeft);
  545. clipToFrustumLeft: {
  546. dist1 = transformedVertices[0] * frustumLeft.x + transformedVertices[1] * frustumLeft.y + transformedVertices[2] * frustumLeft.z;
  547. vertexIndex = 0;
  548. uvtIndex = 0;
  549. _tempClippedVertices.length = 0;
  550. _tempClippedUvtData.length = 0;
  551. len = int(transformedVertices.length / 3);
  552. i = 0;
  553. clipLoopLeft: while(i < len)
  554. {
  555. pt0X = transformedVertices[int(i*3)];
  556. pt0Y = transformedVertices[int(i*3+1)];
  557. pt0Z = transformedVertices[int(i*3+2)];
  558. uv0U = workingUvtData[int(i*3)];
  559. uv0V = workingUvtData[int(i*3+1)];
  560. ii = (i+1 < len) ? i+1 : 0;
  561. pt1X = transformedVertices[int((ii)*3)];
  562. pt1Y = transformedVertices[int((ii)*3+1)];
  563. pt1Z = transformedVertices[int((ii)*3+2)];
  564. uv1U = workingUvtData[int(ii*3)];
  565. uv1V = workingUvtData[int(ii*3+1)];
  566. dist2 = pt1X * frustumLeft.x + pt1Y * frustumLeft.y + pt1Z * frustumLeft.z;
  567. d = dist1 / (dist1-dist2);
  568. if (isNaN(d)) d = 1; // !important, above can give divide by 0 errors.
  569. if( dist1 < 0 && dist2 < 0 ) status = OUTSIDE;
  570. else if( dist1 > 0 && dist2 > 0 ) status = INSIDE;
  571. else if( dist1 > 0 && dist2 < 0 ) status = IN_OUT;
  572. else status = OUT_IN;
  573. switch( status )
  574. {
  575. case INSIDE:
  576. _tempClippedVertices[vertexIndex++] = pt1X;
  577. _tempClippedVertices[vertexIndex++] = pt1Y;
  578. _tempClippedVertices[vertexIndex++] = pt1Z;
  579. _tempClippedUvtData[uvtIndex++] = uv1U;
  580. _tempClippedUvtData[uvtIndex++] = uv1V;
  581. _tempClippedUvtData[uvtIndex++] = 1;
  582. break;
  583. case IN_OUT:
  584. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  585. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  586. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  587. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  588. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  589. _tempClippedUvtData[uvtIndex++] = 1;
  590. break;
  591. case OUT_IN:
  592. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  593. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  594. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  595. _tempClippedVertices[vertexIndex++] = pt1X;
  596. _tempClippedVertices[vertexIndex++] = pt1Y;
  597. _tempClippedVertices[vertexIndex++] = pt1Z;
  598. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  599. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  600. _tempClippedUvtData[uvtIndex++] = 1;
  601. _tempClippedUvtData[uvtIndex++] = uv1U;
  602. _tempClippedUvtData[uvtIndex++] = uv1V;
  603. _tempClippedUvtData[uvtIndex++] = 1;
  604. break;
  605. default:
  606. break;
  607. }
  608. dist1 = dist2;
  609. i++;
  610. }
  611. transformedVertices.length = workingUvtData.length = 0;
  612. len = _tempClippedVertices.length;
  613. for (i=0; i<len; i++) transformedVertices[i] = _tempClippedVertices[i];
  614. for (i=0; i<len; i++) workingUvtData[i] = _tempClippedUvtData[i];
  615. }
  616. if (transformedVertices.length == 0) {
  617. tileInView = false; break clipVerticesBlock;
  618. }
  619. /* write new indices: e.g. triangle FAB, FBC, FCD, FDE where BC and DE have been clipped to frustum.
  620. A _______ B
  621. | \
  622. | \ C
  623. | |
  624. |________/ D
  625. F E
  626. */
  627. tile.clippedIndices.length = 0;
  628. var currIndex_cvb:int = 1;
  629. len = int((transformedVertices.length / 3 - 2) * 3);
  630. for (i = 0; i < len; i+=3) {
  631. workingIndices[i] = 0;
  632. workingIndices[int(i+1)] = currIndex_cvb++;
  633. workingIndices[int(i+2)] = currIndex_cvb;
  634. }
  635. tile.graphicsTrianglePath.indices = workingIndices;
  636. tile.graphicsTrianglePath.uvtData = workingUvtData;
  637. break clipVerticesBlock;
  638. }
  639. //Profiler.instance.end("clip");
  640. if (!tileInView)
  641. { // put tl child tile at head of capicua -> continue with NEXT tile.
  642. if (tile.n != null) {tile.n.next = capicua.cap; if (capicua.cap) capicua.cap.prev = tile.n; capicua.cap = tile.n;}
  643. else {if (capicua.cua != null) capicua.cua.next = null;}
  644. continue selectTiles;
  645. }
  646. if(tile.ppd < pixelsPerDegree && tile.tl != null){
  647. //put tl child tile at head of capicua -> go down quadTree looking for higher res tiles
  648. if (tile.tl != null) {tile.tl.next = capicua.cap; if (capicua.cap) capicua.cap.prev = tile.tl; capicua.cap = tile.tl;}
  649. else {if (capicua.cua != null) capicua.cua.next = null;}
  650. // put tl child tile at head of capicua -> go to next tile as well
  651. if (tile.n != null) {tile.n.next = capicua.cap; if (capicua.cap) capicua.cap.prev = tile.n; capicua.cap = tile.n;}
  652. else {if (capicua.cua != null) capicua.cua.next = null;}
  653. continue selectTiles;
  654. }
  655. // put next tile at head of capicua.
  656. if (tile.n != null) {tile.n.next = capicua.cap; if (capicua.cap) capicua.cap.prev = tile.n; capicua.cap = tile.n;}
  657. else {if (capicua.cua != null) capicua.cua.next = null;}
  658. /* tile has been selected. ***************************/
  659. // check if tile needs loading and temporary uvtData and bitmapData
  660. // check tile.graphicsBitmapFill.bitmapData instead of bitmapData so that this won't execute next frame.
  661. if ( !tile.bitmapLoading && !tile.bitmapLoaded )
  662. {
  663. var tileLoader:TileLoader;
  664. if (__loaders.length > 0) { tileLoader = __loaders[__loaders.length-1]; __loaders.length--; }
  665. else
  666. tileLoader = new TileLoader();
  667. __urlRequest.url = tile.url; //trace("tilw "+tile.url);
  668. //loader.contentLoaderInfo.addEventListener(Event.COMPLETE, tile.bitmapLoadedHandler, false, 1, true);
  669. tileLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, bitmapLoadedHandler, false, 0, true);
  670. tileLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler, false, 0, true);
  671. tileLoader.tile = tile;
  672. tileLoader.timeStamp = flash.utils.getTimer();
  673. tileLoader.viewData = viewData;
  674. tileLoader.load(__urlRequest);
  675. tile.bitmapLoading = true;
  676. }
  677. if (!tile.graphicsBitmapFill.bitmapData){
  678. // walk UP the quadtree looking for the first tile with bitmapData and use that as a preview tile.
  679. var parentTile:Tile = tile.p;
  680. findValidParentTile: while(parentTile != null)
  681. {
  682. if (parentTile.bitmapData != null){
  683. /* found valid parent tile, adjust uvtData so that it will be appropriate for the parent tile */
  684. var tp:TilePyramid = tile.tilePyramid;
  685. var mult:int = 1 << (tile.t - parentTile.t);
  686. var upt1:Number = (parentTile.c+1) * mult * tp.tileSize;
  687. var vpt1:Number = (parentTile.r+1) * mult * tp.tileSize;
  688. if ( upt1 > tp.widths[tile.t]) upt1 = tp.widths[tile.t];
  689. if ( vpt1 > tp.heights[tile.t]) vpt1 = tp.heights[tile.t];
  690. var uBegin:Number = (tile.c - (parentTile.c * mult)) * tp.tileSize / (upt1 - parentTile.c * mult * tp.tileSize);
  691. var vBegin:Number = (tile.r - (parentTile.r * mult)) * tp.tileSize / (vpt1 - parentTile.r * mult * tp.tileSize);
  692. var uEnd:Number = ((tile.c+1) - (parentTile.c * mult)) * tp.tileSize / (upt1 - parentTile.c * mult * tp.tileSize);
  693. var vEnd:Number = ((tile.r+1) - (parentTile.r * mult)) * tp.tileSize / (vpt1 - parentTile.r * mult * tp.tileSize);
  694. if ( uEnd > 1 ) uEnd = 1;
  695. if ( vEnd > 1 ) vEnd = 1;
  696. var uRange:Number = uEnd - uBegin;
  697. var vRange:Number = vEnd - vBegin;
  698. workingUvtData = tile.previewUvtData;
  699. referenceUvtData = tile.uvtData;
  700. i = 0; len = referenceUvtData.length;
  701. // calculate uvtData for preview tile.
  702. while (i<len) {
  703. workingUvtData[i] = uBegin + referenceUvtData[i] * uRange; i++;
  704. workingUvtData[i] = vBegin + referenceUvtData[i] * vRange; i++;
  705. workingUvtData[i] = -1; i++;
  706. }
  707. // copy uvtData and bitmapData over to graphicsData
  708. tile.graphicsTrianglePath.uvtData = tile.previewUvtData = workingUvtData;
  709. tile.graphicsBitmapFill.bitmapData = parentTile.bitmapData;
  710. // add tile to displaying tile list and set displaying
  711. if (displayingTile) { displayingTile.nextDisplayingTile = tile; displayingTile = tile; }
  712. else { _displayingTile = displayingTile = tile; }
  713. displayingTile.displaying = true;
  714. clipReferenceVerticesBlock: {
  715. //transformedVertices.length = 0;
  716. //transform.transformVectors(tile.vertices, // in
  717. // transformedVertices); // out
  718. transformedVertices = referenceTransformedVertices;
  719. referenceUvtData = tile.previewUvtData;
  720. workingUvtData = tile.clippedUvtData;
  721. len = referenceUvtData.length;
  722. workingUvtData.length = 0;
  723. for (i = 0; i < len; i++){ workingUvtData[i] = referenceUvtData[i] }
  724. clipToFrustumPlane( transformedVertices, workingUvtData, frustumTop );
  725. clipToFrustumPlane( transformedVertices, workingUvtData, frustumRight );
  726. clipToFrustumPlane( transformedVertices, workingUvtData, frustumBottom);
  727. clipToFrustumPlane( transformedVertices, workingUvtData, frustumLeft);
  728. tile.graphicsTrianglePath.uvtData = workingUvtData;
  729. break clipReferenceVerticesBlock;
  730. }
  731. break findValidParentTile; // done creating adjusted uvtData.
  732. }
  733. parentTile = parentTile.p; // continue with next parent tile up the list.
  734. }
  735. }
  736. // final check to make sure fill has bitmapData and to check that function was called by Stage.invalidate(): (if (event) );
  737. if (tile.graphicsBitmapFill.bitmapData && (targetGraphics))
  738. {
  739. // update displaying tile list and mark current tile.
  740. if (displayingTile) { // the displayingTile list already contains at least one tile.
  741. displayingTile.nextDisplayingTile = tile; //write link from displayingTile to this tile.
  742. displayingTile = tile; //switch displayingTile reference to this tile.
  743. }
  744. else {
  745. rootTile.displayingTile = displayingTile = tile; //start off the displayingTile list and save reference to first tile in QuadTreeCube.
  746. }
  747. displayingTile.displaying = true; // set displaying.
  748. tile.graphicsTrianglePath.vertices.length = 0;
  749. Utils3D.projectVectors(perspective, transformedVertices, // in
  750. tile.graphicsTrianglePath.vertices, tile.graphicsTrianglePath.uvtData); // out
  751. _graphicsData[graphicsDataIndex++] = tile.graphicsBitmapFill;
  752. _graphicsData[graphicsDataIndex++] = tile.graphicsTrianglePath;
  753. }
  754. }
  755. // end quadtree loop
  756. // check that stage was checked by Stage.invalidate() and render scene.
  757. if ( targetGraphics && _graphicsData.length > 0) {
  758. targetGraphics.clear();
  759. targetGraphics.drawGraphicsData(_graphicsData);
  760. //if (targetGraphics) Profiler.instance.end("render");
  761. //if (targetGraphics) Profiler.instance.endProfiling();
  762. return (_graphicsData.length > 0);
  763. }
  764. //if (targetGraphics) Profiler.instance.end("render");
  765. //if (targetGraphics) Profiler.instance.endProfiling();
  766. return false;
  767. }
  768. //private var stroke : GraphicsStroke = new GraphicsStroke(0.001, false, "normal", "none", "round", 3, new GraphicsSolidFill(0xFF0000));
  769. protected function clipToFrustumPlane( vertices:Vector.<Number>, uvtData:Vector.<Number>, plane:Vector3D):void
  770. {
  771. var dist1:Number = vertices[0] * plane.x + vertices[1] * plane.y + vertices[2] * plane.z;
  772. var vertexIndex:int = 0;
  773. var uvtIndex:int = 0;
  774. _tempClippedVertices.length = 0;
  775. _tempClippedUvtData.length = 0;
  776. var len:int, i:int;
  777. len = int(vertices.length / 3);
  778. i = 0;
  779. clipLoop: while(i < len)
  780. {
  781. var pt0X:Number = vertices[int(i*3)];
  782. var pt0Y:Number = vertices[int(i*3+1)];
  783. var pt0Z:Number = vertices[int(i*3+2)];
  784. var uv0U:Number = uvtData[int(i*3)];
  785. var uv0V:Number = uvtData[int(i*3+1)];
  786. var ii:int = (i+1 < len) ? i+1 : 0;
  787. var pt1X:Number = vertices[int((ii)*3)];
  788. var pt1Y:Number = vertices[int((ii)*3+1)];
  789. var pt1Z:Number = vertices[int((ii)*3+2)];
  790. var uv1U:Number = uvtData[int(ii*3)];
  791. var uv1V:Number = uvtData[int(ii*3+1)];
  792. //_tempPoint.x = pt1X; _tempPoint.y = pt1Y; _tempPoint.z = pt1Z;
  793. //var dist2:Number = plane.dotProduct(_tempPoint);
  794. var dist2:Number = pt1X * plane.x + pt1Y * plane.y + pt1Z * plane.z;
  795. var d:Number = dist1 / (dist1-dist2);
  796. if (isNaN(d)) d = 1; // !important, above can give divide by 0 errors.
  797. var status:uint;
  798. if( dist1 < 0 && dist2 < 0 )
  799. status = OUTSIDE;
  800. else if( dist1 > 0 && dist2 > 0 )
  801. status = INSIDE;
  802. else if( dist1 > 0 && dist2 < 0 )
  803. status = IN_OUT;
  804. else
  805. status = OUT_IN;
  806. switch( status )
  807. {
  808. case INSIDE:
  809. _tempClippedVertices[vertexIndex++] = pt1X;
  810. _tempClippedVertices[vertexIndex++] = pt1Y;
  811. _tempClippedVertices[vertexIndex++] = pt1Z;
  812. _tempClippedUvtData[uvtIndex++] = uv1U;
  813. _tempClippedUvtData[uvtIndex++] = uv1V;
  814. _tempClippedUvtData[uvtIndex++] = 1;
  815. break;
  816. case IN_OUT:
  817. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  818. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  819. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  820. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  821. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  822. _tempClippedUvtData[uvtIndex++] = 1;
  823. break;
  824. case OUT_IN:
  825. _tempClippedVertices[vertexIndex++] = pt0X + (pt1X - pt0X) * d;
  826. _tempClippedVertices[vertexIndex++] = pt0Y + (pt1Y - pt0Y) * d;
  827. _tempClippedVertices[vertexIndex++] = pt0Z + (pt1Z - pt0Z) * d;
  828. _tempClippedVertices[vertexIndex++] = pt1X;
  829. _tempClippedVertices[vertexIndex++] = pt1Y;
  830. _tempClippedVertices[vertexIndex++] = pt1Z;
  831. _tempClippedUvtData[uvtIndex++] = uv0U + (uv1U - uv0U) * d;
  832. _tempClippedUvtData[uvtIndex++] = uv0V + (uv1V - uv0V) * d;
  833. _tempClippedUvtData[uvtIndex++] = 1;
  834. _tempClippedUvtData[uvtIndex++] = uv1U;
  835. _tempClippedUvtData[uvtIndex++] = uv1V;
  836. _tempClippedUvtData[uvtIndex++] = 1;
  837. break;
  838. default:
  839. break;
  840. }
  841. dist1 = dist2;
  842. i++;
  843. }
  844. vertices.length = uvtData.length = 0;
  845. len = _tempClippedVertices.length;
  846. for (i=0; i<len; i++) vertices[i] = _tempClippedVertices[i];
  847. for (i=0; i<len; i++) uvtData[i] = _tempClippedUvtData[i];
  848. }
  849. //TODO: make this static? function so that Tile.rootParentLoadComplete handler is the same...
  850. final public function bitmapLoadedHandler(event:Event):void
  851. {
  852. var loaderInfo:LoaderInfo = LoaderInfo(event.target);
  853. var tileLoader:TileLoader = loaderInfo.loader as TileLoader;
  854. var tile:Tile = tileLoader.tile
  855. tile.bitmapLoading = false;
  856. tile.bitmapLoaded = true;
  857. tile.previewUvtData.length = 0;
  858. tile.bitmapData = tile.graphicsBitmapFill.bitmapData = (loaderInfo.content as Bitmap).bitmapData;
  859. tile.graphicsTrianglePath.uvtData = tile.uvtData;
  860. if ( tile.t > 0 ){
  861. var expirationTimer:Timer;
  862. if (tile.expirationTimer != null) expirationTimer = tile.expirationTimer;
  863. //else expirationTimer = tile.expirationTimer = new Timer( 180000/(1<<tile.t) );
  864. else expirationTimer = tile.expirationTimer = new Timer( 90000 );
  865. expirationTimer.addEventListener( TimerEvent.TIMER, tile.expirationHandler, false, 0, true);
  866. expirationTimer.start();
  867. }
  868. var viewData:ViewData = tileLoader.viewData;
  869. viewData.invalid = viewData.invalidPerspective = true;
  870. if (viewData.stage != null) viewData.stage.invalidate();
  871. _loadingStatistics.reportLatency( getTimer() - tileLoader.timeStamp)
  872. loaderInfo.removeEventListener( Event.COMPLETE, bitmapLoadedHandler );
  873. loaderInfo.removeEventListener( IOErrorEvent.IO_ERROR, IOErrorEventHandler );
  874. tileLoader.tile = null;
  875. tileLoader.timeStamp = NaN;
  876. tileLoader.viewData = null;
  877. __loaders[ __loaders.length ] = tileLoader;
  878. }
  879. // public function get canvas():Sprite { return _canvas; }
  880. // public function get secondaryCanvas():Sprite { return _secondaryCanvas; }
  881. // public function get canvasInternal():Sprite { return canvasInternal; }
  882. // public function get secondaryCanvasInternal():Sprite { return _secondaryCanvasInternal; }
  883. // public function get managedChildren():Sprite { return _managedChildren; }
  884. // public function get secondaryManagedChildren():Sprite { return _secondaryManagedChildren; }
  885. // public function get children():Sprite { return _children; };
  886. // protected function clearGraphics(e:Event):void {
  887. // if (_viewData._path == null) _canvasInternal.graphics.clear();
  888. // if (_viewData.secondaryViewData._path == null) _secondaryCanvasInternal.graphics.clear();
  889. // }
  890. }
  891. }
  892. // protected function prependRotation(axis:Vector3D, angle:Number):Vector.<Number> {
  893. // var v:Vector.<Number>=new Vector.<Number>(16,true);
  894. // var sinW2:Number = Math.sin(angle*0.5);
  895. // var x:Number = axis.x * sinW2;
  896. // var y:Number = axis.y * sinW2;
  897. // var z:Number = axis.z * sinW2;
  898. // var w:Number = Math.cos(angle*0.5);
  899. // v[0] = (1-2*y*y-2*z*z);
  900. // v[1] = (2*x*y+2*w*z);
  901. // v[2] = (2*x*z-2*w*y);
  902. // v[3]=0;
  903. // v[4] = (2*x*y-2*w*z);
  904. // v[5] = (1-2*x*x-2*z*z);
  905. // v[6] = (2*y*z+2*w*x);
  906. // v[7]=0;
  907. // v[8] = (2*x*z+2*w*y);
  908. // v[9] = (2*y*z-2*w*x);
  909. // v[10] = (1-2*x*x-2*y*y);
  910. // v[11]=0;
  911. // v[12]=0; //translation X
  912. // v[13]=0; //translation Y
  913. // v[14]=0; //translation Z
  914. // v[15]=1;
  915. // return v;
  916. // }
  917. //
  918. // protected function matrix3DMultiply(lhs:Matrix3D, rhs:Matrix3D):Matrix3D
  919. // {
  920. // var v:Vector.<Number> = new Vector.<Number>();
  921. // var l:Vector.<Number> = lhs.rawData;
  922. // var r:Vector.<Number> = rhs.rawData;
  923. //
  924. // v[0] = l[0] * r[0] + l[1] * r[4] + l[2] * r[8];
  925. // v[1] = l[0] * r[1] + l[1] * r[5] + l[2] * r[9];
  926. // v[2] = l[0] * r[2] + l[1] * r[6] + l[2] * r[10];
  927. // v[3] = l[0] * r[3] + l[1] * r[7] + l[2] * r[11] + l[3];
  928. //
  929. // v[4] = l[4] * r[0] + l[5] * r[4] + l[6] * r[8];
  930. // v[5] = l[4] * r[1] + l[5] * r[5] + l[6] * r[9];
  931. // v[6] = l[4] * r[2] + l[5] * r[6] + l[6] * r[10];
  932. // v[7] = l[4] * r[3] + l[5] * r[7] + l[6] * r[11] + l[7];
  933. //
  934. // v[8] = l[8] * r[0] + l[9] * r[4] + l[10] * r[8];
  935. // v[9] = l[8] * r[1] + l[9] * r[5] + l[10] * r[9];
  936. // v[10] = l[8] * r[2] + l[9] * r[6] + l[10] * r[10];
  937. // v[11] = l[8] * r[3] + l[9] * r[7] + l[10] * r[11] + l[11];
  938. //
  939. // v[12] = 0
  940. // v[13] = 0
  941. // v[14] = 0
  942. // v[15] = 1
  943. // lhs.rawData = v;
  944. // return lhs;
  945. // }
  946. // var rotationX:Number = -gimbal.rotationX * Math.PI/180;
  947. // var rotationY:Number = -pano.rotationY * Math.PI/180;
  948. // var facing:Vector3D = new Vector3D(
  949. // Math.sin( rotationY ) * Math.cos( rotationX ),
  950. // -Math.sin( rotationX ),
  951. // Math.cos( rotationY ) * Math.cos( rotationX )
  952. // );