public void addVertex(Vertex newVertex) { newVertex.parent=this; vertexData.Add(newVertex); dirty=true; }
public void removeVertex(Vertex v) { vertexData.Remove(v); }
public void addTriangle(Vertex a, Vertex b, Vertex c) { addTriangle(new Triangle(a,b,c)); }
public void addVertex(float x, float y, float z, float u, float v) { Vertex vert=new Vertex(x,y,z); vert.setUV(u,v); addVertex(vert); }
public void meshSmooth() { rebuild(); Triangle tri; float u,v; Vertex a,b,c,d,e,f,temp; Vector ab,bc,ca,nab,nbc,nca,center; float sab,sbc,sca,rab,rbc,rca; float uab,vab,ubc,vbc,uca,vca; float sqrt3=(float)Math.Sqrt(3f); for (int i=0;i<triangles;i++) { tri=Triangle(i); a=tri.p1; b=tri.p2; c=tri.p3; ab=Vector.Scale(0.5f,Vector.Add(b.pos,a.pos)); bc = Vector.Scale(0.5f, Vector.Add(c.pos, b.pos)); ca = Vector.Scale(0.5f, Vector.Add(a.pos, c.pos)); rab=Vector.Subtract(ab,a.pos).Length(); rbc = Vector.Subtract(bc, b.pos).Length(); rca = Vector.Subtract(ca, c.pos).Length(); nab=Vector.Scale(0.5f,Vector.Add(a.n,b.n)); nbc = Vector.Scale(0.5f, Vector.Add(b.n, c.n)); nca = Vector.Scale(0.5f, Vector.Add(c.n, a.n)); uab=0.5f*(a.Tu+b.Tu); vab=0.5f*(a.Tv+b.Tv); ubc=0.5f*(b.Tu+c.Tu); vbc=0.5f*(b.Tv+c.Tv); uca=0.5f*(c.Tu+a.Tu); vca=0.5f*(c.Tv+a.Tv); sab=1f-nab.Length(); sbc = 1f - nbc.Length(); sca = 1f - nca.Length(); nab.Normalize(); nbc.Normalize(); nca.Normalize(); d=new Vertex(Vector.Subtract(ab,Vector.Scale(rab*sab,nab)),uab,vab); e = new Vertex(Vector.Subtract(bc, Vector.Scale(rbc * sbc, nbc)), ubc, vbc); f = new Vertex(Vector.Subtract(ca, Vector.Scale(rca * sca, nca)), uca, vca); addVertex(d); addVertex(e); addVertex(f); tri.p2=d; tri.p3=f; addTriangle(b,e,d); addTriangle(c,f,e); addTriangle(d,e,f); } removeDuplicateVertices(); }
public void Render(Triangle tri) { if (!ready) return; if (tri.parent == null) return; if ((mode & W) != 0) { drawWireframe(tri, color); if ((mode & W) == 0) return; } p1 = tri.p1; p2 = tri.p2; p3 = tri.p3; if (p1.Y > p2.Y) { tempVertex = p1; p1 = p2; p2 = tempVertex; } if (p2.Y > p3.Y) { tempVertex = p2; p2 = p3; p3 = tempVertex; } if (p1.Y > p2.Y) { tempVertex = p1; p1 = p2; p2 = tempVertex; } if (p1.Y >= height) return; if (p3.Y < 0) return; if (p1.Y == p3.Y) return; if (mode == F) { lutID = (int) (tri.n2.X * 127 + 127) + ((int) (tri.n2.Y * 127 + 127) << 8); c = ColorUtility.multiply(color, diffuse[lutID]); s = ColorUtility.scale(specular[lutID], reflectivity); currentColor = ColorUtility.add(c, s); } currentId = (tri.parent.id << 16) | tri.id; x1 = p1.X << 8; x2 = p2.X << 8; x3 = p3.X << 8; y1 = p1.Y; y2 = p2.Y; y3 = p3.Y; x4 = x1 + (x3 - x1) * (y2 - y1) / (y3 - y1); x1 <<= 8; x2 <<= 8; x3 <<= 8; x4 <<= 8; z1 = p1.Z; z2 = p2.Z; z3 = p3.Z; nx1 = p1.nx << 16; nx2 = p2.nx << 16; nx3 = p3.nx << 16; ny1 = p1.ny << 16; ny2 = p2.ny << 16; ny3 = p3.ny << 16; tx1 = p1.tx << 16; tx2 = p2.tx << 16; tx3 = p3.tx << 16; ty1 = p1.ty << 16; ty2 = p2.ty << 16; ty3 = p3.ty << 16; dx = (x4 - x2) >> 16; if (dx == 0) return; temp = 256 * (y2 - y1) / (y3 - y1); z4 = z1 + ((z3 - z1) >> 8) * temp; nx4 = nx1 + ((nx3 - nx1) >> 8) * temp; ny4 = ny1 + ((ny3 - ny1) >> 8) * temp; tx4 = tx1 + ((tx3 - tx1) >> 8) * temp; ty4 = ty1 + ((ty3 - ty1) >> 8) * temp; dz = (z4 - z2) / dx; dnx = (nx4 - nx2) / dx; dny = (ny4 - ny2) / dx; dtx = (tx4 - tx2) / dx; dty = (ty4 - ty2) / dx; if (dx < 0) { temp = x2; x2 = x4; x4 = temp; z2 = z4; tx2 = tx4; ty2 = ty4; nx2 = nx4; ny2 = ny4; } if (y2 >= 0) { dy = y2 - y1; if (dy != 0) { dxL = (x2 - x1) / dy; dxR = (x4 - x1) / dy; dzBase = (z2 - z1) / dy; dnxBase = (nx2 - nx1) / dy; dnyBase = (ny2 - ny1) / dy; dtxBase = (tx2 - tx1) / dy; dtyBase = (ty2 - ty1) / dy; } xBase = x1; xMax = x1; zBase = z1; nxBase = nx1; nyBase = ny1; txBase = tx1; tyBase = ty1; if (y1 < 0) { xBase -= y1 * dxL; xMax -= y1 * dxR; zBase -= y1 * dzBase; nxBase -= y1 * dnxBase; nyBase -= y1 * dnyBase; txBase -= y1 * dtxBase; tyBase -= y1 * dtyBase; y1 = 0; } y2 = (y2 < height) ? y2 : height; offset = y1 * width; for (y = y1; y < y2; y++) renderLine(); } if (y2 < height) { dy = y3 - y2; if (dy != 0) { dxL = (x3 - x2) / dy; dxR = (x3 - x4) / dy; dzBase = (z3 - z2) / dy; dnxBase = (nx3 - nx2) / dy; dnyBase = (ny3 - ny2) / dy; dtxBase = (tx3 - tx2) / dy; dtyBase = (ty3 - ty2) / dy; } xBase = x2; xMax = x4; zBase = z2; nxBase = nx2; nyBase = ny2; txBase = tx2; tyBase = ty2; if (y2 < 0) { xBase -= y2 * dxL; xMax -= y2 * dxR; zBase -= y2 * dzBase; nxBase -= y2 * dnxBase; nyBase -= y2 * dnyBase; txBase -= y2 * dtxBase; tyBase -= y2 * dtyBase; y2 = 0; } y3 = (y3 < height) ? y3 : height; offset = y2 * width; for (y = y2; y < y3; y++) renderLine(); } }
private void drawLine(Vertex a, Vertex b, uint color) { Vertex temp; if ((a.clipcode & b.clipcode) != 0) return; dx = (int) Math.Abs(a.X - b.X); dy = (int) Math.Abs(a.Y - b.Y); dz = 0; if (dx > dy) { if (a.X > b.X) { temp = a; a = b; b = temp; } if (dx > 0) { dz = (b.Z - a.Z) / dx; dy = ((b.Y - a.Y) << 16) / dx; } z = a.Z; y = a.Y << 16; for (x = a.X; x <= b.X; x++) { y2 = y >> 16; if (MathUtility.inrange(x, 0, width - 1) && MathUtility.inrange(y2, 0, height - 1)) { offset = y2 * width; if (z < zBuffer[x + offset]) { if (!screen.antialias) { screen.p[x + offset] = color; zBuffer[x + offset] = (uint) z; } else { screen.p[x + offset] = color; screen.p[x + offset + 1] = color; screen.p[x + offset + width] = color; screen.p[x + offset + width + 1] = color; zBuffer[x + offset] = (uint) z; } } if (useIdBuffer) idBuffer[x + offset] = currentId; } z += dz; y += dy; } } else { if (a.Y > b.Y) { temp = a; a = b; b = temp; } if (dy > 0) { dz = (b.Z - a.Z) / dy; dx = ((b.X - a.X) << 16) / dy; } z = a.Z; x = a.X << 16; for (y = a.Y; y <= b.Y; y++) { x2 = x >> 16; if (MathUtility.inrange(x2, 0, width - 1) && MathUtility.inrange(y, 0, height - 1)) { offset = y * width; if (z < zBuffer[x2 + offset]) { if (!screen.antialias) { screen.p[x2 + offset] = color; zBuffer[x2 + offset] = (uint) z; } else { screen.p[x2 + offset] = color; screen.p[x2 + offset + 1] = color; screen.p[x2 + offset + width] = color; screen.p[x2 + offset + width + 1] = color; zBuffer[x2 + offset] = (uint) z; } } if (useIdBuffer) idBuffer[x2 + offset] = currentId; } z += dz; x += dx; } } }
public bool equals(Vertex v, float tolerance) { return Math.Abs(Vector.Subtract(pos, v.pos).Length()) < tolerance; }
public bool equals(Vertex v) { return ((pos.X == v.pos.X) && (pos.Y == v.pos.Y) && (pos.Z == v.pos.Z)); }
public Vertex Clone() { Vertex newVertex = new Vertex(); newVertex.pos = pos.Clone(); newVertex.n = n.Clone(); newVertex.Tu = Tu; newVertex.Tv = Tv; return newVertex; }
void drawLine(Vertex a, Vertex b, uint color) { Vertex temp; if ((a.clipcode & b.clipcode) != 0) { return; } dx = Math.Abs(a.X - b.X); dy = Math.Abs(a.Y - b.Y); dz = 0; if (dx > dy) { if (a.X > b.X) { temp = a; a = b; b = temp; } if (dx > 0) { dz = (b.Z - a.Z) / dx; dy = ((b.Y - a.Y) << 16) / dx; } z = a.Z; y = a.Y << 16; var bX = b.X; int xPlusOffset; for (x = a.X; x <= bX; x++) { y2 = y >> 16; if (MathUtility.inrange(x, 0, width - 1) && MathUtility.inrange(y2, 0, height - 1)) { offset = y2 * width; xPlusOffset = x + offset; if (z < zBuffer[xPlusOffset]) { if (!screen.antialias) { screen.p[xPlusOffset] = color; zBuffer[xPlusOffset] = (uint)z; } else { screen.p[xPlusOffset] = color; screen.p[xPlusOffset + 1] = color; screen.p[xPlusOffset + width] = color; screen.p[xPlusOffset + width + 1] = color; zBuffer[xPlusOffset] = (uint)z; } } if (useIdBuffer) { idBuffer[xPlusOffset] = currentId; } } z += dz; y += dy; } } else { if (a.Y > b.Y) { temp = a; a = b; b = temp; } if (dy > 0) { dz = (b.Z - a.Z) / dy; dx = ((b.X - a.X) << 16) / dy; } z = a.Z; x = a.X << 16; int bY = b.Y; int x2PlusOffset; for (y = a.Y; y <= bY; y++) { x2 = x >> 16; if (MathUtility.inrange(x2, 0, width - 1) && MathUtility.inrange(y, 0, height - 1)) { offset = y * width; x2PlusOffset = x2 + offset; if (z < zBuffer[x2PlusOffset]) { if (!screen.antialias) { screen.p[x2PlusOffset] = color; zBuffer[x2PlusOffset] = (uint)z; } else { screen.p[x2PlusOffset] = color; screen.p[x2PlusOffset + 1] = color; screen.p[x2PlusOffset + width] = color; screen.p[x2PlusOffset + width + 1] = color; zBuffer[x2PlusOffset] = (uint)z; } } if (useIdBuffer) { idBuffer[x2PlusOffset] = currentId; } } z += dz; x += dx; } } }
public void Render(Triangle tri) { if (!ready) { return; } if (tri.getParent() == null) { return; } if ((mode & Wireframe) != 0) { drawWireframe(tri, color); if ((mode & Wireframe) == 0) { return; } } p1 = tri.p1; p2 = tri.p2; p3 = tri.p3; if (p1.Y > p2.Y) { tempVertex = p1; p1 = p2; p2 = tempVertex; } if (p2.Y > p3.Y) { tempVertex = p2; p2 = p3; p3 = tempVertex; } if (p1.Y > p2.Y) { tempVertex = p1; p1 = p2; p2 = tempVertex; } if (p1.Y >= height) { return; } if (p3.Y < 0) { return; } if (p1.Y == p3.Y) { return; } if (mode == Flat) { lutID = (int)(tri.n2.X * 127 + 127) + ((int)(tri.n2.Y * 127 + 127) << 8); c = ColorUtility.multiply(color, diffuse[lutID]); s = ColorUtility.scale(specular[lutID], reflectivity); currentColor = ColorUtility.add(c, s); } currentId = (tri.getParent().id << 16) | tri.id; x1 = p1.X << 8; x2 = p2.X << 8; x3 = p3.X << 8; y1 = p1.Y; y2 = p2.Y; y3 = p3.Y; x4 = x1 + (x3 - x1) * (y2 - y1) / (y3 - y1); x1 <<= 8; x2 <<= 8; x3 <<= 8; x4 <<= 8; z1 = p1.Z; z2 = p2.Z; z3 = p3.Z; nx1 = p1.nx << 16; nx2 = p2.nx << 16; nx3 = p3.nx << 16; ny1 = p1.ny << 16; ny2 = p2.ny << 16; ny3 = p3.ny << 16; tx1 = p1.tx << 16; tx2 = p2.tx << 16; tx3 = p3.tx << 16; ty1 = p1.ty << 16; ty2 = p2.ty << 16; ty3 = p3.ty << 16; dx = (x4 - x2) >> 16; if (dx == 0) { return; } temp = 256 * (y2 - y1) / (y3 - y1); z4 = z1 + ((z3 - z1) >> 8) * temp; nx4 = nx1 + ((nx3 - nx1) >> 8) * temp; ny4 = ny1 + ((ny3 - ny1) >> 8) * temp; tx4 = tx1 + ((tx3 - tx1) >> 8) * temp; ty4 = ty1 + ((ty3 - ty1) >> 8) * temp; dz = (z4 - z2) / dx; dnx = (nx4 - nx2) / dx; dny = (ny4 - ny2) / dx; dtx = (tx4 - tx2) / dx; dty = (ty4 - ty2) / dx; if (dx < 0) { temp = x2; x2 = x4; x4 = temp; z2 = z4; tx2 = tx4; ty2 = ty4; nx2 = nx4; ny2 = ny4; } if (y2 >= 0) { dy = y2 - y1; if (dy != 0) { dxL = (x2 - x1) / dy; dxR = (x4 - x1) / dy; dzBase = (z2 - z1) / dy; dnxBase = (nx2 - nx1) / dy; dnyBase = (ny2 - ny1) / dy; dtxBase = (tx2 - tx1) / dy; dtyBase = (ty2 - ty1) / dy; } xBase = x1; xMax = x1; zBase = z1; nxBase = nx1; nyBase = ny1; txBase = tx1; tyBase = ty1; if (y1 < 0) { xBase -= y1 * dxL; xMax -= y1 * dxR; zBase -= y1 * dzBase; nxBase -= y1 * dnxBase; nyBase -= y1 * dnyBase; txBase -= y1 * dtxBase; tyBase -= y1 * dtyBase; y1 = 0; } y2 = (y2 < height) ? y2 : height; offset = y1 * width; for (y = y1; y < y2; y++) { renderLine(); } } if (y2 < height) { dy = y3 - y2; if (dy != 0) { dxL = (x3 - x2) / dy; dxR = (x3 - x4) / dy; dzBase = (z3 - z2) / dy; dnxBase = (nx3 - nx2) / dy; dnyBase = (ny3 - ny2) / dy; dtxBase = (tx3 - tx2) / dy; dtyBase = (ty3 - ty2) / dy; } xBase = x2; xMax = x4; zBase = z2; nxBase = nx2; nyBase = ny2; txBase = tx2; tyBase = ty2; if (y2 < 0) { xBase -= y2 * dxL; xMax -= y2 * dxR; zBase -= y2 * dzBase; nxBase -= y2 * dnxBase; nyBase -= y2 * dnyBase; txBase -= y2 * dtxBase; tyBase -= y2 * dtyBase; y2 = 0; } y3 = (y3 < height) ? y3 : height; offset = y2 * width; for (y = y2; y < y3; y++) { renderLine(); } } }