PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/as3/trunk/src/org/papervision3d/core/render/command/RenderTriangle.as

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