Polygon.hx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. package h3d.prim;
  2. import h3d.col.Point;
  3. class Polygon extends MeshPrimitive {
  4. public var points : Array<Point>;
  5. public var normals : Array<Point>;
  6. public var tangents : Array<Point>;
  7. public var uvs : Array<UV>;
  8. public var idx : hxd.IndexBuffer;
  9. public var colors : Array<Point>;
  10. var scaled = 1.;
  11. var translatedX = 0.;
  12. var translatedY = 0.;
  13. var translatedZ = 0.;
  14. public function new( points, ?idx ) {
  15. this.points = points;
  16. this.idx = idx;
  17. }
  18. override function getBounds() {
  19. var b = new h3d.col.Bounds();
  20. for( p in points )
  21. b.addPoint(p);
  22. return b;
  23. }
  24. override function alloc( engine : h3d.Engine ) {
  25. dispose();
  26. var format = hxd.BufferFormat.POS3D;
  27. if( normals != null )
  28. format = format.append("normal", DVec3);
  29. if( tangents != null )
  30. format = format.append("tangent", DVec3);
  31. if( uvs != null )
  32. format = format.append("uv", DVec2);
  33. if( colors != null )
  34. format = format.append("color", DVec3);
  35. var buf = new hxd.FloatBuffer();
  36. for( k in 0...points.length ) {
  37. var p = points[k];
  38. buf.push(p.x);
  39. buf.push(p.y);
  40. buf.push(p.z);
  41. if( normals != null ) {
  42. var n = normals[k];
  43. buf.push(n.x);
  44. buf.push(n.y);
  45. buf.push(n.z);
  46. }
  47. if( tangents != null ) {
  48. var t = tangents[k];
  49. buf.push(t.x);
  50. buf.push(t.y);
  51. buf.push(t.z);
  52. }
  53. if( uvs != null ) {
  54. var t = uvs[k];
  55. buf.push(t.u);
  56. buf.push(t.v);
  57. }
  58. if( colors != null ) {
  59. var c = colors[k];
  60. buf.push(c.x);
  61. buf.push(c.y);
  62. buf.push(c.z);
  63. }
  64. }
  65. buffer = h3d.Buffer.ofFloats(buf, format);
  66. if( idx != null )
  67. indexes = h3d.Indexes.alloc(idx);
  68. }
  69. public function unindex() {
  70. if( idx != null && points.length != idx.length ) {
  71. var p = [];
  72. var used = [];
  73. for( i in 0...idx.length )
  74. p.push(points[idx[i]].clone());
  75. if( normals != null ) {
  76. var n = [];
  77. for( i in 0...idx.length )
  78. n.push(normals[idx[i]].clone());
  79. normals = n;
  80. }
  81. if( tangents != null ) {
  82. var t = [];
  83. for( i in 0...idx.length )
  84. t.push(tangents[idx[i]].clone());
  85. tangents = t;
  86. }
  87. if( colors != null ) {
  88. var n = [];
  89. for( i in 0...idx.length )
  90. n.push(colors[idx[i]].clone());
  91. colors = n;
  92. }
  93. if( uvs != null ) {
  94. var t = [];
  95. for( i in 0...idx.length )
  96. t.push(uvs[idx[i]].clone());
  97. uvs = t;
  98. }
  99. points = p;
  100. idx = null;
  101. }
  102. }
  103. public function translate( dx : Float, dy : Float, dz : Float ) {
  104. translatedX += dx;
  105. translatedY += dy;
  106. translatedZ += dz;
  107. for( p in points ) {
  108. p.x += dx;
  109. p.y += dy;
  110. p.z += dz;
  111. }
  112. }
  113. public function scale( s : Float ) {
  114. scaled *= s;
  115. for( p in points ) {
  116. p.x *= s;
  117. p.y *= s;
  118. p.z *= s;
  119. }
  120. }
  121. public function addNormals() {
  122. // make per-point normal
  123. normals = new Array();
  124. for( i in 0...points.length )
  125. normals[i] = new Point();
  126. var pos = 0;
  127. for( i in 0...triCount() ) {
  128. var i0, i1, i2;
  129. if( idx == null ) {
  130. i0 = pos++;
  131. i1 = pos++;
  132. i2 = pos++;
  133. } else {
  134. i0 = idx[pos++];
  135. i1 = idx[pos++];
  136. i2 = idx[pos++];
  137. }
  138. var p0 = points[i0];
  139. var p1 = points[i1];
  140. var p2 = points[i2];
  141. // this is the per-face normal
  142. var n = p1.sub(p0).cross(p2.sub(p0));
  143. // add it to each point
  144. normals[i0].x += n.x; normals[i0].y += n.y; normals[i0].z += n.z;
  145. normals[i1].x += n.x; normals[i1].y += n.y; normals[i1].z += n.z;
  146. normals[i2].x += n.x; normals[i2].y += n.y; normals[i2].z += n.z;
  147. }
  148. // normalize all normals
  149. for( n in normals )
  150. n.normalize();
  151. }
  152. public function addTangents() {
  153. if( normals == null )
  154. addNormals();
  155. if( uvs == null )
  156. addUVs();
  157. tangents = [];
  158. for( i in 0...points.length )
  159. tangents[i] = new Point();
  160. var pos = 0;
  161. for( i in 0...triCount() ) {
  162. var i0, i1, i2;
  163. if( idx == null ) {
  164. i0 = pos++;
  165. i1 = pos++;
  166. i2 = pos++;
  167. } else {
  168. i0 = idx[pos++];
  169. i1 = idx[pos++];
  170. i2 = idx[pos++];
  171. }
  172. var p0 = points[i0];
  173. var p1 = points[i1];
  174. var p2 = points[i2];
  175. var uv0 = uvs[i0];
  176. var uv1 = uvs[i1];
  177. var uv2 = uvs[i2];
  178. var n = normals[i0];
  179. var k0 = p1.sub(p0);
  180. var k1 = p2.sub(p0);
  181. k0.scale(uv2.v - uv0.v);
  182. k1.scale(uv1.v - uv0.v);
  183. var t = k0.sub(k1);
  184. var b = n.cross(t);
  185. b.normalize();
  186. t = b.cross(n);
  187. t.normalize();
  188. // add it to each point
  189. tangents[i0].x += t.x; tangents[i0].y += t.y; tangents[i0].z += t.z;
  190. tangents[i1].x += t.x; tangents[i1].y += t.y; tangents[i1].z += t.z;
  191. tangents[i2].x += t.x; tangents[i2].y += t.y; tangents[i2].z += t.z;
  192. }
  193. for( t in tangents )
  194. t.normalize();
  195. }
  196. public function addUVs() {
  197. uvs = [];
  198. for( i in 0 ... points.length )
  199. uvs[i] = new UV(points[i].x, points[i].y);
  200. }
  201. public function uvScale( su : Float, sv : Float ) {
  202. if( uvs == null )
  203. throw "Missing UVs";
  204. var m = new Map<UV,Bool>();
  205. for( t in uvs ) {
  206. if( m.exists(t) ) continue;
  207. m.set(t, true);
  208. t.u *= su;
  209. t.v *= sv;
  210. }
  211. }
  212. override function triCount() {
  213. var n = super.triCount();
  214. if( n != 0 )
  215. return n;
  216. return Std.int((idx == null ? points.length : idx.length) / 3);
  217. }
  218. override function vertexCount() {
  219. return points.length;
  220. }
  221. override function getCollider() : h3d.col.Collider {
  222. var vertexes = new haxe.ds.Vector<hxd.impl.Float32>(points.length * 3);
  223. var indexes = new haxe.ds.Vector<Int>(idx.length);
  224. var vid = 0;
  225. for( p in points ) {
  226. vertexes[vid++] = p.x;
  227. vertexes[vid++] = p.y;
  228. vertexes[vid++] = p.z;
  229. }
  230. for( i in 0...idx.length )
  231. indexes[i] = idx[i];
  232. var poly = new h3d.col.Polygon();
  233. poly.addBuffers(vertexes, indexes);
  234. return poly;
  235. }
  236. override function render( engine : h3d.Engine ) {
  237. if( buffer == null || buffer.isDisposed() )
  238. alloc(engine);
  239. var indexes = indexes;
  240. var count = triCount();
  241. if( indexes == null )
  242. indexes = engine.mem.getTriIndexes(count*3);
  243. if( buffers != null )
  244. engine.renderMultiBuffers(formats, buffers, indexes, 0, count);
  245. else
  246. engine.renderIndexed(buffer, indexes, 0, count);
  247. }
  248. }