123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- package h3d.prim;
- import h3d.col.Point;
- class Polygon extends MeshPrimitive {
- public var points : Array<Point>;
- public var normals : Array<Point>;
- public var tangents : Array<Point>;
- public var uvs : Array<UV>;
- public var idx : hxd.IndexBuffer;
- public var colors : Array<Point>;
- var scaled = 1.;
- var translatedX = 0.;
- var translatedY = 0.;
- var translatedZ = 0.;
- public function new( points, ?idx ) {
- this.points = points;
- this.idx = idx;
- }
- override function getBounds() {
- var b = new h3d.col.Bounds();
- for( p in points )
- b.addPoint(p);
- return b;
- }
- override function alloc( engine : h3d.Engine ) {
- dispose();
- var format = hxd.BufferFormat.POS3D;
- if( normals != null )
- format = format.append("normal", DVec3);
- if( tangents != null )
- format = format.append("tangent", DVec3);
- if( uvs != null )
- format = format.append("uv", DVec2);
- if( colors != null )
- format = format.append("color", DVec3);
- var buf = new hxd.FloatBuffer();
- for( k in 0...points.length ) {
- var p = points[k];
- buf.push(p.x);
- buf.push(p.y);
- buf.push(p.z);
- if( normals != null ) {
- var n = normals[k];
- buf.push(n.x);
- buf.push(n.y);
- buf.push(n.z);
- }
- if( tangents != null ) {
- var t = tangents[k];
- buf.push(t.x);
- buf.push(t.y);
- buf.push(t.z);
- }
- if( uvs != null ) {
- var t = uvs[k];
- buf.push(t.u);
- buf.push(t.v);
- }
- if( colors != null ) {
- var c = colors[k];
- buf.push(c.x);
- buf.push(c.y);
- buf.push(c.z);
- }
- }
- buffer = h3d.Buffer.ofFloats(buf, format);
- if( idx != null )
- indexes = h3d.Indexes.alloc(idx);
- }
- public function unindex() {
- if( idx != null && points.length != idx.length ) {
- var p = [];
- var used = [];
- for( i in 0...idx.length )
- p.push(points[idx[i]].clone());
- if( normals != null ) {
- var n = [];
- for( i in 0...idx.length )
- n.push(normals[idx[i]].clone());
- normals = n;
- }
- if( tangents != null ) {
- var t = [];
- for( i in 0...idx.length )
- t.push(tangents[idx[i]].clone());
- tangents = t;
- }
- if( colors != null ) {
- var n = [];
- for( i in 0...idx.length )
- n.push(colors[idx[i]].clone());
- colors = n;
- }
- if( uvs != null ) {
- var t = [];
- for( i in 0...idx.length )
- t.push(uvs[idx[i]].clone());
- uvs = t;
- }
- points = p;
- idx = null;
- }
- }
- public function translate( dx : Float, dy : Float, dz : Float ) {
- translatedX += dx;
- translatedY += dy;
- translatedZ += dz;
- for( p in points ) {
- p.x += dx;
- p.y += dy;
- p.z += dz;
- }
- }
- public function scale( s : Float ) {
- scaled *= s;
- for( p in points ) {
- p.x *= s;
- p.y *= s;
- p.z *= s;
- }
- }
- public function addNormals() {
- // make per-point normal
- normals = new Array();
- for( i in 0...points.length )
- normals[i] = new Point();
- var pos = 0;
- for( i in 0...triCount() ) {
- var i0, i1, i2;
- if( idx == null ) {
- i0 = pos++;
- i1 = pos++;
- i2 = pos++;
- } else {
- i0 = idx[pos++];
- i1 = idx[pos++];
- i2 = idx[pos++];
- }
- var p0 = points[i0];
- var p1 = points[i1];
- var p2 = points[i2];
- // this is the per-face normal
- var n = p1.sub(p0).cross(p2.sub(p0));
- // add it to each point
- normals[i0].x += n.x; normals[i0].y += n.y; normals[i0].z += n.z;
- normals[i1].x += n.x; normals[i1].y += n.y; normals[i1].z += n.z;
- normals[i2].x += n.x; normals[i2].y += n.y; normals[i2].z += n.z;
- }
- // normalize all normals
- for( n in normals )
- n.normalize();
- }
- public function addTangents() {
- if( normals == null )
- addNormals();
- if( uvs == null )
- addUVs();
- tangents = [];
- for( i in 0...points.length )
- tangents[i] = new Point();
- var pos = 0;
- for( i in 0...triCount() ) {
- var i0, i1, i2;
- if( idx == null ) {
- i0 = pos++;
- i1 = pos++;
- i2 = pos++;
- } else {
- i0 = idx[pos++];
- i1 = idx[pos++];
- i2 = idx[pos++];
- }
- var p0 = points[i0];
- var p1 = points[i1];
- var p2 = points[i2];
- var uv0 = uvs[i0];
- var uv1 = uvs[i1];
- var uv2 = uvs[i2];
- var n = normals[i0];
- var k0 = p1.sub(p0);
- var k1 = p2.sub(p0);
- k0.scale(uv2.v - uv0.v);
- k1.scale(uv1.v - uv0.v);
- var t = k0.sub(k1);
- var b = n.cross(t);
- b.normalize();
- t = b.cross(n);
- t.normalize();
- // add it to each point
- tangents[i0].x += t.x; tangents[i0].y += t.y; tangents[i0].z += t.z;
- tangents[i1].x += t.x; tangents[i1].y += t.y; tangents[i1].z += t.z;
- tangents[i2].x += t.x; tangents[i2].y += t.y; tangents[i2].z += t.z;
- }
- for( t in tangents )
- t.normalize();
- }
- public function addUVs() {
- uvs = [];
- for( i in 0 ... points.length )
- uvs[i] = new UV(points[i].x, points[i].y);
- }
- public function uvScale( su : Float, sv : Float ) {
- if( uvs == null )
- throw "Missing UVs";
- var m = new Map<UV,Bool>();
- for( t in uvs ) {
- if( m.exists(t) ) continue;
- m.set(t, true);
- t.u *= su;
- t.v *= sv;
- }
- }
- override function triCount() {
- var n = super.triCount();
- if( n != 0 )
- return n;
- return Std.int((idx == null ? points.length : idx.length) / 3);
- }
- override function vertexCount() {
- return points.length;
- }
- override function getCollider() : h3d.col.Collider {
- var vertexes = new haxe.ds.Vector<hxd.impl.Float32>(points.length * 3);
- var indexes = new haxe.ds.Vector<Int>(idx.length);
- var vid = 0;
- for( p in points ) {
- vertexes[vid++] = p.x;
- vertexes[vid++] = p.y;
- vertexes[vid++] = p.z;
- }
- for( i in 0...idx.length )
- indexes[i] = idx[i];
- var poly = new h3d.col.Polygon();
- poly.addBuffers(vertexes, indexes);
- return poly;
- }
- override function render( engine : h3d.Engine ) {
- if( buffer == null || buffer.isDisposed() )
- alloc(engine);
- var indexes = indexes;
- var count = triCount();
- if( indexes == null )
- indexes = engine.mem.getTriIndexes(count*3);
- if( buffers != null )
- engine.renderMultiBuffers(formats, buffers, indexes, 0, count);
- else
- engine.renderIndexed(buffer, indexes, 0, count);
- }
- }
|