public async Task <FragmentMap> GetFragmentMap(Enviroment enviroment, Camera camera) { var fragmentMap = new FragmentMap() { Fragments = new FragmentInfo[camera.ScreenWidth * camera.ScreenHeight], LastPosIndex = 0, NotEmptyPositions = new int[camera.ScreenWidth * camera.ScreenHeight] }; var allPolys = enviroment.GetPrimitives() .SelectMany(p => p.GetLocalPolys(camera)) .Where(p => this.Observed(p, camera)); await Task.Run(() => { Parallel.ForEach(allPolys, (p) => this.GetAllFragmentsFromPoly(p, camera, fragmentMap)); }); return(fragmentMap); }
private void InterpolationStep( int xStart, int xSteps, int xDir, Vector3 startUp, Vector3 startDown, Vector2 startTexUp, Vector2 startTexDown, Vector3 startNormalUp, Vector3 startNormalDown, float startProectionUp, float startProectionDown, Vector3 startUpDelta, Vector3 startDownDelta, Vector2 startTexUpDelta, Vector2 startTexDownDelta, Vector3 startNormalUpDelta, Vector3 startNormalDownDelta, float startProectionUpDelta, float startProectionDownDelta, Camera camera, FragmentMap fragmentMap) { for (int i = 0; i <= xSteps; i++) { Vector3 pos = startDown; Vector3 norm = startNormalDown; Vector2 tex = startTexDown; Vector3 delta, deltaNormal; Vector2 deltaTexture; if (startProectionUp > 0) { int steps; int up = (int)startProectionUp, down = (int)startProectionDown; int diffU = camera.ScreenHeight - 1 - up; if (diffU < 0) { up = camera.ScreenHeight - 1; } steps = up - down; if (steps != 0) { delta = (startUp - startDown) / steps; deltaTexture = (startTexUp - startTexDown) / steps; deltaNormal = (startNormalUp - startNormalDown) / steps; } else { delta = Vector3.Zero; deltaNormal = Vector3.Zero; deltaTexture = Vector2.Zero; } if (down < 0) { pos -= delta * down; tex -= deltaTexture * down; norm -= deltaNormal * down; steps += down; down = 0; } int x = xStart + (i * xDir); for (int g = 0; g <= steps; g++) { int y = down + g; int index = y * camera.ScreenWidth + x; if (fragmentMap.Fragments[index] == null) { var frag = new FragmentInfo( pos, norm, tex, new Vector2(x, y)) { Color = int.MaxValue }; fragmentMap.Fragments[index] = frag; Monitor.Enter(this.locker); fragmentMap.NotEmptyPositions[fragmentMap.LastPosIndex] = index; fragmentMap.LastPosIndex++; Monitor.Exit(this.locker); } else if (fragmentMap.Fragments[index].Coordinate.Z > pos.Z) { var frag = new FragmentInfo( pos, norm, tex, new Vector2(x, y)) { Color = int.MaxValue }; fragmentMap.Fragments[index] = frag; } pos += delta; norm += deltaNormal; tex += deltaTexture; } } startDown += startDownDelta; startUp += startUpDelta; startTexDown += startTexDownDelta; startTexUp += startTexUpDelta; startNormalDown += startNormalDownDelta; startNormalUp += startNormalUpDelta; startProectionDown += startProectionDownDelta; startProectionUp += startProectionUpDelta; } }
private void GetAllFragmentsFromPoly(Poly poly, Camera camera, FragmentMap fragmentMap) { var v1p = camera.ScreenProection(poly.v1.Position); var v2p = camera.ScreenProection(poly.v2.Position); var v3p = camera.ScreenProection(poly.v3.Position); if (v1p.X > v2p.X) { var w = v1p; v1p = v2p; v2p = w; var v = poly.v1; poly.v1 = poly.v2; poly.v2 = v; } if (v2p.X > v3p.X) { var w = v2p; v2p = v3p; v3p = w; var v = poly.v2; poly.v2 = poly.v3; poly.v3 = v; } if (v1p.X > v2p.X) { var w = v1p; v1p = v2p; v2p = w; var v = poly.v1; poly.v1 = poly.v2; poly.v2 = v; } int x1 = (int)v1p.X; int x2 = (int)v2p.X; int x3 = (int)v3p.X; int x12 = x2 - x1; int x13 = x3 - x1; int x32 = x3 - x2; Vector3 u, d, du, dd, nu, nd, dnu, dnd; Vector2 tu, td, dtu, dtd; float pu, pd, dpu, dpd; int rDiff; if (x2 > 0 && x1 < camera.ScreenWidth) { u = poly.v1.Position; d = poly.v1.Position; tu = poly.v1.TextureCoord; td = poly.v1.TextureCoord; nu = poly.v1.Normal; nd = poly.v1.Normal; pu = v1p.Y; pd = v1p.Y; if (x12 != 0) { dpu = (v2p.Y - v1p.Y) / x12; dpd = (v3p.Y - v1p.Y) / x13; if (dpu > dpd) { du = (poly.v2.Position - poly.v1.Position) / x12; dtu = (poly.v2.TextureCoord - poly.v1.TextureCoord) / x12; dnu = (poly.v2.Normal - poly.v1.Normal) / x12; dd = (poly.v3.Position - poly.v1.Position) / x13; dtd = (poly.v3.TextureCoord - poly.v1.TextureCoord) / x13; dnd = (poly.v3.Normal - poly.v1.Normal) / x13; } else { var t = dpu; dpu = dpd; dpd = t; du = (poly.v3.Position - poly.v1.Position) / x13; dtu = (poly.v3.TextureCoord - poly.v1.TextureCoord) / x13; dnu = (poly.v3.Normal - poly.v1.Normal) / x13; dd = (poly.v2.Position - poly.v1.Position) / x12; dtd = (poly.v2.TextureCoord - poly.v1.TextureCoord) / x12; dnd = (poly.v2.Normal - poly.v1.Normal) / x12; } } else { dpu = 0; dpd = 0; dtu = Vector2.Zero; dtd = Vector2.Zero; dnu = Vector3.Zero; dnd = Vector3.Zero; du = Vector3.Zero; dd = Vector3.Zero; } rDiff = camera.ScreenWidth - 1 - x2; if (rDiff < 0) { x12 += rDiff; } if (x1 < 0) { x12 += x1; u -= du * x1; d -= dd * x1; tu -= dtu * x1; td -= dtd * x1; nu -= dnu * x1; nd -= dnd * x1; pu -= dpu * x1; pd -= dpd * x1; x1 = 0; } this.InterpolationStep(x1, x12, 1, u, d, tu, td, nu, nd, pu, pd, du, dd, dtu, dtd, dnu, dnd, dpu, dpd, camera, fragmentMap); } if (x2 < camera.ScreenWidth && x3 > 0) { u = poly.v3.Position; d = poly.v3.Position; tu = poly.v3.TextureCoord; td = poly.v3.TextureCoord; nu = poly.v3.Normal; nd = poly.v3.Normal; pu = v3p.Y; pd = v3p.Y; if (x32 != 0) { dpu = (v2p.Y - v3p.Y) / x32; dpd = (v1p.Y - v3p.Y) / x13; if (dpu > dpd) { du = (poly.v2.Position - poly.v3.Position) / x32; dtu = (poly.v2.TextureCoord - poly.v3.TextureCoord) / x32; dnu = (poly.v2.Normal - poly.v3.Normal) / x32; dd = (poly.v1.Position - poly.v3.Position) / x13; dtd = (poly.v1.TextureCoord - poly.v3.TextureCoord) / x13; dnd = (poly.v1.Normal - poly.v3.Normal) / x13; } else { var t = dpu; dpu = dpd; dpd = t; du = (poly.v1.Position - poly.v3.Position) / x13; dtu = (poly.v1.TextureCoord - poly.v3.TextureCoord) / x13; dnu = (poly.v1.Normal - poly.v3.Normal) / x13; dd = (poly.v2.Position - poly.v3.Position) / x32; dtd = (poly.v2.TextureCoord - poly.v3.TextureCoord) / x32; dnd = (poly.v2.Normal - poly.v3.Normal) / x32; } } else { dpu = 0; dpd = 0; dtu = Vector2.Zero; dtd = Vector2.Zero; dnu = Vector3.Zero; dnd = Vector3.Zero; du = Vector3.Zero; dd = Vector3.Zero; } if (x2 < 0) { x32 += x2; x2 = 0; } rDiff = camera.ScreenWidth - 1 - x3; if (rDiff < 0) { x32 += rDiff; u -= du * rDiff; d -= dd * rDiff; tu -= dtu * rDiff; td -= dtd * rDiff; nu -= dnu * rDiff; nd -= dnd * rDiff; pu -= dpu * rDiff; pd -= dpd * rDiff; x3 = camera.ScreenWidth - 1; } this.InterpolationStep(x3, x32, -1, u, d, tu, td, nu, nd, pu, pd, du, dd, dtu, dtd, dnu, dnd, dpu, dpd, camera, fragmentMap); } }