PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/fp10/src/org/papervision3d/core/render/command/RenderTriangle.as

http://papervision3d.googlecode.com/
ActionScript | 401 lines | 321 code | 67 blank | 13 comment | 61 complexity | 56ef7c70932bf4376ec7b84f2adf9872 MD5 | raw file
  1. package org.papervision3d.core.render.command
  2. {
  3. /**
  4. * @Author Ralph Hauwert
  5. */
  6. import org.papervision3d.core.geom.renderables.Triangle3D;
  7. import org.papervision3d.core.geom.renderables.Vertex3DInstance;
  8. import org.papervision3d.core.math.Matrix3D;
  9. import org.papervision3d.core.math.Number3D;
  10. import org.papervision3d.core.math.NumberUV;
  11. import org.papervision3d.core.proto.MaterialObject3D;
  12. import org.papervision3d.core.render.data.RenderHitData;
  13. import org.papervision3d.core.render.data.RenderSessionData;
  14. import org.papervision3d.core.render.draw.ITriangleDrawer;
  15. import org.papervision3d.materials.BitmapMaterial;
  16. import org.papervision3d.materials.MovieMaterial;
  17. import flash.display.BitmapData;
  18. import flash.display.Graphics;
  19. import flash.display.GraphicsTrianglePath;
  20. import flash.display.IGraphicsData;
  21. import flash.display.Sprite;
  22. import flash.geom.Point;
  23. import flash.geom.Rectangle;
  24. public class RenderTriangle extends RenderableListItem implements IRenderListItem
  25. {
  26. protected static var resBA:Vertex3DInstance = new Vertex3DInstance();
  27. protected static var resPA:Vertex3DInstance = new Vertex3DInstance();
  28. protected static var resRA:Vertex3DInstance = new Vertex3DInstance();
  29. protected static var vPoint:Vertex3DInstance = new Vertex3DInstance();
  30. private var position:Number3D = new Number3D();
  31. public var triangle:Triangle3D;
  32. public var container:Sprite;
  33. public var renderer:ITriangleDrawer;
  34. public var renderMat:MaterialObject3D;
  35. /*
  36. Drawing Variables
  37. */
  38. public var v0:Vertex3DInstance;
  39. public var v1:Vertex3DInstance;
  40. public var v2:Vertex3DInstance;
  41. public var uv0:NumberUV;
  42. public var uv1:NumberUV;
  43. public var uv2:NumberUV;
  44. //for creating new RT from store. See TriangleMesh3D createDrawTriangle
  45. public var create:Function;
  46. public function RenderTriangle(triangle:Triangle3D):void
  47. {
  48. this.triangle = triangle;
  49. this.instance = triangle.instance;
  50. renderableInstance = triangle;
  51. renderable = Triangle3D;
  52. this.v0 = triangle.v0.vertex3DInstance;
  53. this.v1 = triangle.v1.vertex3DInstance;
  54. this.v2 = triangle.v2.vertex3DInstance;
  55. this.uv0 = triangle.uv0;
  56. this.uv1 = triangle.uv1;
  57. this.uv2 = triangle.uv2;
  58. this.renderer = triangle.material;
  59. update();
  60. }
  61. override public function render(renderSessionData:RenderSessionData, graphics:Graphics):void
  62. {
  63. renderer.drawTriangle(this, graphics, renderSessionData);
  64. }
  65. protected var vPointL:Vertex3DInstance;
  66. protected var vx0:Vertex3DInstance;
  67. protected var vx1:Vertex3DInstance;
  68. protected var vx2:Vertex3DInstance;
  69. override public function hitTestPoint2D(point:Point, renderhitData:RenderHitData):RenderHitData
  70. {
  71. renderMat = triangle.material;
  72. if( !renderMat ) renderMat = triangle.instance.material;
  73. if(renderMat && renderMat.interactive){
  74. vPointL = RenderTriangle.vPoint;
  75. vPointL.x = point.x;
  76. vPointL.y = point.y;
  77. vx0 = triangle.v0.vertex3DInstance;
  78. vx1 = triangle.v1.vertex3DInstance;
  79. vx2 = triangle.v2.vertex3DInstance;
  80. if(sameSide(vPointL,vx0,vx1,vx2)){
  81. if(sameSide(vPointL,vx1,vx0,vx2)){
  82. if(sameSide(vPointL,vx2,vx0,vx1)){
  83. return deepHitTest(triangle, vPointL, renderhitData);
  84. }
  85. }
  86. }
  87. }
  88. return renderhitData;
  89. }
  90. public function sameSide(point:Vertex3DInstance, ref:Vertex3DInstance, a:Vertex3DInstance, b:Vertex3DInstance):Boolean
  91. {
  92. Vertex3DInstance.subTo(b,a,resBA);
  93. Vertex3DInstance.subTo(point,a,resPA);
  94. Vertex3DInstance.subTo(ref, a, resRA);
  95. return Vertex3DInstance.cross(resBA, resPA)*Vertex3DInstance.cross(resBA, resRA) >= 0;
  96. }
  97. private function deepHitTest(face:Triangle3D, vPoint:Vertex3DInstance, rhd:RenderHitData):RenderHitData
  98. {
  99. var v0:Vertex3DInstance = face.v0.vertex3DInstance;
  100. var v1:Vertex3DInstance = face.v1.vertex3DInstance;
  101. var v2:Vertex3DInstance = face.v2.vertex3DInstance;
  102. var v0_x : Number = v2.x - v0.x;
  103. var v0_y : Number = v2.y - v0.y;
  104. var v1_x : Number = v1.x - v0.x;
  105. var v1_y : Number = v1.y - v0.y;
  106. var v2_x : Number = vPoint.x - v0.x;
  107. var v2_y : Number = vPoint.y - v0.y;
  108. var dot00 : Number = v0_x * v0_x + v0_y * v0_y;
  109. var dot01 : Number = v0_x * v1_x + v0_y * v1_y;
  110. var dot02 : Number = v0_x * v2_x + v0_y * v2_y;
  111. var dot11 : Number = v1_x * v1_x + v1_y * v1_y;
  112. var dot12 : Number = v1_x * v2_x + v1_y * v2_y;
  113. var invDenom : Number = 1 / (dot00 * dot11 - dot01 * dot01);
  114. var u : Number = (dot11 * dot02 - dot01 * dot12) * invDenom;
  115. var v : Number = (dot00 * dot12 - dot01 * dot02) * invDenom;
  116. var rv0_x : Number = face.v2.x - face.v0.x;
  117. var rv0_y : Number = face.v2.y - face.v0.y;
  118. var rv0_z : Number = face.v2.z - face.v0.z;
  119. var rv1_x : Number = face.v1.x - face.v0.x;
  120. var rv1_y : Number = face.v1.y - face.v0.y;
  121. var rv1_z : Number = face.v1.z - face.v0.z;
  122. var hx:Number = face.v0.x + rv0_x*u + rv1_x*v;
  123. var hy:Number = face.v0.y + rv0_y*u + rv1_y*v;
  124. var hz:Number = face.v0.z + rv0_z*u + rv1_z*v;
  125. //From interactive utils
  126. var uv:Array = face.uv;
  127. var uu0 : Number = uv[0].u;
  128. var uu1 : Number = uv[1].u;
  129. var uu2 : Number = uv[2].u;
  130. var uv0 : Number = uv[0].v;
  131. var uv1 : Number = uv[1].v;
  132. var uv2 : Number = uv[2].v;
  133. var v_x : Number = ( uu1 - uu0 ) * v + ( uu2 - uu0 ) * u + uu0;
  134. var v_y : Number = ( uv1 - uv0 ) * v + ( uv2 - uv0 ) * u + uv0;
  135. if( triangle.material )
  136. renderMat = face.material;
  137. else
  138. renderMat = face.instance.material;
  139. var bitmap:BitmapData = renderMat.bitmap;
  140. var width:Number = 1;
  141. var height:Number = 1;
  142. var dx:Number = 0;
  143. var dy:Number = 0;
  144. // MovieMaterial rect
  145. if( renderMat is MovieMaterial )
  146. {
  147. var movieRenderMat:MovieMaterial = renderMat as MovieMaterial;
  148. var rect:Rectangle = movieRenderMat.rect;
  149. if( rect )
  150. {
  151. dx = rect.x;
  152. dy = rect.y;
  153. width = rect.width;
  154. height = rect.height;
  155. }
  156. }
  157. else if( bitmap )
  158. {
  159. width = BitmapMaterial.AUTO_MIP_MAPPING ? renderMat.widthOffset : bitmap.width;
  160. height = BitmapMaterial.AUTO_MIP_MAPPING ? renderMat.heightOffset : bitmap.height;
  161. }
  162. //end from interactive utils
  163. rhd.displayObject3D = face.instance;
  164. rhd.material = renderMat;
  165. rhd.renderable = face;
  166. rhd.hasHit = true;
  167. position.x = hx;
  168. position.y = hy;
  169. position.z = hz;
  170. Matrix3D.multiplyVector( face.instance.world, position );
  171. rhd.x = position.x; //hx;
  172. rhd.y = position.y; //hy;
  173. rhd.z = position.z; //hz;
  174. rhd.u = v_x * width + dx;
  175. rhd.v = height - v_y * height + dy;
  176. return rhd;
  177. }
  178. public override function update():void{
  179. if (v0.x > v1.x) {
  180. if (v0.x > v2.x) maxX = v0.x;
  181. else maxX = v2.x;
  182. } else {
  183. if (v1.x > v2.x) maxX = v1.x;
  184. else maxX = v2.x;
  185. }
  186. if (v0.x < v1.x) {
  187. if (v0.x < v2.x) minX = v0.x;
  188. else minX = v2.x;
  189. } else {
  190. if (v1.x < v2.x) minX = v1.x;
  191. else minX = v2.x;
  192. }
  193. if (v0.y > v1.y) {
  194. if (v0.y > v2.y) maxY = v0.y;
  195. else maxY = v2.y;
  196. } else {
  197. if (v1.y > v2.y) maxY = v1.y;
  198. else maxY = v2.y;
  199. }
  200. if (v0.y < v1.y) {
  201. if (v0.y < v2.y) minY = v0.y;
  202. else minY = v2.y;
  203. } else {
  204. if (v1.y < v2.y) minY = v1.y;
  205. else minY = v2.y;
  206. }
  207. if (v0.z > v1.z) {
  208. if (v0.z > v2.z) maxZ = v0.z;
  209. else maxZ = v2.z;
  210. } else {
  211. if (v1.z > v2.z) maxZ = v1.z;
  212. else maxZ = v2.z;
  213. }
  214. if (v0.z < v1.z) {
  215. if (v0.z < v2.z) minZ = v0.z;
  216. else minZ = v2.z;
  217. } else {
  218. if (v1.z < v2.z) minZ = v1.z;
  219. else minZ = v2.z;
  220. }
  221. screenZ = (v0.z + v1.z + v2.z) / 3;
  222. area = 0.5 * (v0.x*(v2.y - v1.y) + v1.x*(v0.y - v2.y) + v2.x*(v1.y - v0.y));
  223. }
  224. public function fivepointcut(v0:Vertex3DInstance, v01:Vertex3DInstance, v1:Vertex3DInstance, v12:Vertex3DInstance, v2:Vertex3DInstance, uv0:NumberUV, uv01:NumberUV, uv1:NumberUV, uv12:NumberUV, uv2:NumberUV):Array
  225. {
  226. if (v0.distanceSqr(v12) < v01.distanceSqr(v2))
  227. {
  228. return [
  229. create(renderableInstance, renderer, v0, v01, v12, uv0, uv01, uv12),
  230. create(renderableInstance, renderer, v01, v1, v12, uv01, uv1, uv12),
  231. create(renderableInstance, renderer, v0, v12 , v2, uv0, uv12, uv2)];
  232. }
  233. else
  234. {
  235. return [
  236. create(renderableInstance, renderer, v0, v01, v2, uv0, uv01, uv2),
  237. create(renderableInstance, renderer, v01, v1, v12, uv01, uv1, uv12),
  238. create(renderableInstance, renderer, v01, v12, v2, uv01, uv12, uv2)];
  239. }
  240. }
  241. public override final function getZ(x:Number, y:Number, focus:Number):Number
  242. {
  243. ax = v0.x;
  244. ay = v0.y;
  245. az = v0.z;
  246. bx = v1.x;
  247. by = v1.y;
  248. bz = v1.z;
  249. cx = v2.x;
  250. cy = v2.y;
  251. cz = v2.z;
  252. if ((ax == x) && (ay == y))
  253. return az;
  254. if ((bx == x) && (by == y))
  255. return bz;
  256. if ((cx == x) && (cy == y))
  257. return cz;
  258. azf = az / focus;
  259. bzf = bz / focus;
  260. czf = cz / focus;
  261. faz = 1 + azf;
  262. fbz = 1 + bzf;
  263. fcz = 1 + czf;
  264. axf = ax*faz - x*azf;
  265. bxf = bx*fbz - x*bzf;
  266. cxf = cx*fcz - x*czf;
  267. ayf = ay*faz - y*azf;
  268. byf = by*fbz - y*bzf;
  269. cyf = cy*fcz - y*czf;
  270. det = axf*(byf - cyf) + bxf*(cyf - ayf) + cxf*(ayf - byf);
  271. da = x*(byf - cyf) + bxf*(cyf - y) + cxf*(y - byf);
  272. db = axf*(y - cyf) + x*(cyf - ayf) + cxf*(ayf - y);
  273. dc = axf*(byf - y) + bxf*(y - ayf) + x*(ayf - byf);
  274. return (da*az + db*bz + dc*cz) / det;
  275. }
  276. public override final function quarter(focus:Number):Array
  277. {
  278. if (area < 20)
  279. return null;
  280. v01 = Vertex3DInstance.median(v0, v1, focus);
  281. v12 = Vertex3DInstance.median(v1, v2, focus);
  282. v20 = Vertex3DInstance.median(v2, v0, focus);
  283. uv01 = NumberUV.median(uv0, uv1);
  284. uv12 = NumberUV.median(uv1, uv2);
  285. uv20 = NumberUV.median(uv2, uv0);
  286. return [
  287. create(renderableInstance, renderer, v0, v01, v20, uv0, uv01, uv20),
  288. create(renderableInstance, renderer, v1, v12, v01, uv1, uv12, uv01),
  289. create(renderableInstance, renderer, v2, v20, v12, uv2, uv20, uv12),
  290. create(renderableInstance, renderer, v01, v12, v20, uv01, uv12, uv20)
  291. ];
  292. }
  293. /*
  294. Don't touch these - needed for quad
  295. */
  296. private var ax:Number;
  297. private var ay:Number;
  298. private var az:Number;
  299. private var bx:Number;
  300. private var by:Number;
  301. private var bz:Number;
  302. private var cx:Number;
  303. private var cy:Number;
  304. private var cz:Number;
  305. private var azf:Number;
  306. private var bzf:Number;
  307. private var czf:Number;
  308. private var faz:Number;
  309. private var fbz:Number;
  310. private var fcz:Number;
  311. private var axf:Number;
  312. private var bxf:Number;
  313. private var cxf:Number;
  314. private var ayf:Number;
  315. private var byf:Number;
  316. private var cyf:Number;
  317. private var det:Number;
  318. private var da:Number;
  319. private var db:Number;
  320. private var dc:Number;
  321. private var au:Number;
  322. private var av:Number;
  323. private var bu:Number;
  324. private var bv:Number;
  325. private var cu:Number;
  326. private var cv:Number;
  327. private var v01:Vertex3DInstance;
  328. private var v12:Vertex3DInstance;
  329. private var v20:Vertex3DInstance;
  330. private var uv01:NumberUV;
  331. private var uv12:NumberUV;
  332. private var uv20:NumberUV;
  333. }
  334. }