/// <inheritdoc /> public async Task <OutputDataModel> AggregateAsync(List <OutputDataModel> models) { return(await Task.Run( () => { if (models.Count == 1) { return models.First(); } var outputModel = new OutputDataModel(); var firstOutputDataModel = models.First(); foreach (var idAndIntersection in firstOutputDataModel.Intersections) { var intersectionId = idAndIntersection.Key; var streets = idAndIntersection.Value.IncomingStreets; var streetsByName = streets.ToDictionary(options => options.StreetName, options => options); var intersectionFromOtherOutputs = models.Skip(1) .Where(model => model.Intersections.ContainsKey(intersectionId)) .Select(model => model.Intersections[intersectionId]) .ToList(); var foundStreets = intersectionFromOtherOutputs .SelectMany( fromOther => fromOther.IncomingStreets .Where(incStreet => streetsByName.ContainsKey(incStreet.StreetName))) .GroupBy(incStreet => incStreet.StreetName) .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList()); var intersectionOptionsUpdated = new IntersectionOptions(); var streetOptionsUpdated = streets .Select( street => { if (foundStreets.TryGetValue(street.StreetName, out var relatedStreets)) { return new StreetOptions { StreetName = street.StreetName, GreenLightDuration = (street.GreenLightDuration + relatedStreets.Sum(relStreet => relStreet.GreenLightDuration)) / (1 + relatedStreets.Count) }; } return street; }) .ToList(); intersectionOptionsUpdated.Id = intersectionId; intersectionOptionsUpdated.IncomingStreets.AddRange( streetOptionsUpdated); outputModel.Intersections.Add(intersectionId, intersectionOptionsUpdated); } return outputModel; })); }
public static bool Has(this IntersectionOptions val, IntersectionOptions f) { //return val.HasFlag(f); return ((uint)val & (uint)f).Equals((uint)f); }
public void GetIntersection(ref RayData PathRay, ref RayHit hit, ref SurfaceIntersectionData idata, IntersectionOptions flags) { EvalIntersectionAdvanced(ref PathRay, ref hit, ref idata, flags); }
private void EvalIntersectionAdvanced(ref RayData PathRay, ref RayHit hit, ref SurfaceIntersectionData ii, IntersectionOptions options) { ITriangleMesh mesh = null; #if VERBOSE try { #endif var currentTriangleIndex = (int)hit.Index; bool isLight = scene.IsLight(currentTriangleIndex); ii.Hit = hit; ii.isLight = isLight; mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex); if (mesh == null) //|| mesh.MeshName.Equals("COL254_01", StringComparison.InvariantCultureIgnoreCase)) { //ii.Color = new RgbSpectrum(1f); //Debugger.Break(); throw new ApplicationException("Invalid triangle index " + currentTriangleIndex + " Mesh not found"); } var meshMat = mesh.MaterialID; ii.isVolume = scene.IsVolumeTriangle(currentTriangleIndex); ii.MMaterial = scene.MatLib.GetSurfMat(meshMat); var matInfo = scene.MaterialProvider.Get(meshMat); mesh.InterpolateTriUV(currentTriangleIndex, hit.U, hit.V, out ii.TexCoords); if (ii.isVolume) { var volumeMaterialInfo = vm.GetMaterialInfo(mesh.MaterialID); vmSampler.Sample(volumeMaterialInfo, ii.Hit.Distance, ref PathRay, out ii.VolumeData); //texSampler.SampleTexture(hit.U, hit.V, volumeMaterialInfo.Density, out ii.VolumeData.Density); //this.texSampler.SampleTexture(hit.U, hit.V, new NoiseTexture() ii.VolumeData.Density); //return; } mesh.InterpolateTriangleNormal((int)hit.Index, hit.U, hit.V, ref ii.Normal); //ii.Normal = scene.Triangles[currentTriangleIndex].ComputeNormal(scene.Vertices).Normalize(); // ii.TexCoords = new UV(hit.U, hit.V); if (isLight) { if (!options.Has(IntersectionOptions.ResumeOnLight)) return; var color = scene.GetLightByIndex((int)hit.Index).Profile.Evaluate(hit.U, hit.V); ii.Color = options.Has(IntersectionOptions.ResolveSpectralDistributions) ? ColorFactory.ToRgb(ref color) : (RgbSpectrum)(RgbSpectrumInfo)color; } if (options.Has(IntersectionOptions.ResolvePartialDerivatives)) { var p1 = scene.Vertices[scene.Triangles[currentTriangleIndex].v0.VertexIndex]; var p2 = scene.Vertices[scene.Triangles[currentTriangleIndex].v1.VertexIndex]; var p3 = scene.Vertices[scene.Triangles[currentTriangleIndex].v2.VertexIndex]; var mt = scene.sceneData.GeoData.TexCoords; var uv1 = mt[scene.sceneData.Triangles[currentTriangleIndex].v0.TexCoordIndex]; var uv2 = mt[scene.sceneData.Triangles[currentTriangleIndex].v1.TexCoordIndex]; var uv3 = mt[scene.sceneData.Triangles[currentTriangleIndex].v2.TexCoordIndex]; float du1 = uv1.x - uv3.x; float du2 = uv2.x - uv3.x; float dv1 = uv1.y - uv3.y; float dv2 = uv2.y - uv3.y; Vector dp1 = Vector.Sub(ref p1, ref p3), dp2 = Vector.Sub(ref p2, ref p3); float determinant = du1 * dv2 - dv1 * du2; if (determinant.NearEqual(0f)) { // Handle zero determinant for triangle partial derivative matrix Vector e1 = p2 - p1; Vector e2 = p3 - p1; Vector.CoordinateSystem(Vector.Normalize(Vector.Cross(ref e2, ref e1)), out ii.DpDu, out ii.DpDv); } else { float invdet = 1f / determinant; ii.DpDu = (dv2 * dp1 - dv1 * dp2) * invdet; ii.DpDv = (-du2 * dp1 + du1 * dp2) * invdet; } } if (matInfo.Alpha is ConstTextureInfo) { ii.Alpha = (matInfo.Alpha as ConstTextureInfo).Color; } if (options.Has(IntersectionOptions.ResolveTextures)) { var diffuseTex = scene.Query(meshMat, TextureType.Diffuse); if (diffuseTex != null) { #if !TEXSAMP RgbSpectrumInfo cc = diffuseTex.Sample(ii.TexCoords.U, ii.TexCoords.V); #else RgbSpectrumInfo cc; texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, diffuseTex, out cc); #endif ii.Color = new RgbSpectrum(cc.c1, cc.c2, cc.c3); //ii.Color = diffuseTex.Sample(ii.TexCoords.U, ii.TexCoords.V); //ii.Color = diffuseTex.Sample(hit.U, hit.V); } else { ii.Color = RgbSpectrum.Max(ref matInfo.Ks, ref matInfo.Kd); } var bump = new Vector(0f); Vector v1, v2; Normal geoNormal = ii.Normal; Vector.CoordinateSystem(ref geoNormal, out v1, out v2); var bumpTex = scene.Query(meshMat, TextureType.Bump); if (bumpTex != null) { var map = bumpTex; var dudv = map.DUDV; RgbSpectrumInfo bs; #if TEXSAMP texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, bumpTex, out bs); #else bs = bumpTex.Sample(ii.TexCoords.U, ii.TexCoords.V); #endif float b0 = bs.Filter(); UV uvdu = new UV(ii.TexCoords.U + dudv.U, ii.TexCoords.V); #if TEXSAMP texSampler.SampleTexture(uvdu.U, uvdu.V, bumpTex, out bs); #else bs = bumpTex.Sample(uvdu.U, uvdu.V); #endif float bu = bs.Filter(); UV uvdv = new UV(ii.TexCoords.U, ii.TexCoords.V + dudv.V); #if TEXSAMP texSampler.SampleTexture(uvdv.U, uvdv.V, bumpTex, out bs); #else bs = bumpTex.Sample(uvdv.U, uvdv.V); #endif float bv = bs.Filter(); float scale = 1.0f; //bm->GetScale(); bump = new Vector(scale * (bu - b0), scale * (bv - b0), 1f); ii.Normal = new Normal( v1.x * bump.x + v2.x * bump.y + geoNormal.x * bump.z, v1.y * bump.x + v2.y * bump.y + geoNormal.y * bump.z, v1.z * bump.x + v2.z * bump.y + geoNormal.z * bump.z).Normalize(); } var nfScale = 2.0f; var nfIscale = 0.5f; var normTex = scene.Query(meshMat, TextureType.Normal); if (normTex != null) { RgbSpectrumInfo color; texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, normTex, out color); float x = nfScale * (color.c1 - nfIscale); float y = nfScale * (color.c2 - nfIscale); float z = nfScale * (color.c3 - nfIscale); ii.Normal = new Normal( v1.x * x + v2.x * y + geoNormal.x * z, v1.y * x + v2.y * y + geoNormal.y * z, v1.z * x + v2.z * y + geoNormal.z * z).Normalize(); } RgbSpectrumInfo reflectance = matInfo.Coefficients[3]; //(RgbSpectrumInfo) matInfo.SpecularReflectance; var reflTex = scene.Query(meshMat, TextureType.Reflection); if (reflTex != null) { texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, reflTex, out reflectance); } RgbSpectrumInfo alpha = null; var alphaTex = scene.Query(meshMat, TextureType.Alpha); if (alphaTex != null) { texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, alphaTex, out alpha); } var zero = new RgbSpectrum(0f); if (ii.TextureData == null) { ii.TextureData = new SurfaceTextureData() { T0 = 0.5f, Transmittance = matInfo.Ks, Exponent = matInfo.Exponent, Alpha = alpha != null ? (RgbSpectrum) alpha : zero, Diffuse = ii.Color, Roughness = bump, Bump = bump, Medium = MediumInfo.Glass, Specular = (RgbSpectrum) reflectance }; } else { ii.TextureData.T0 = 0.5f; ii.TextureData.Transmittance = matInfo.Ks; ii.TextureData.Exponent = matInfo.Exponent; ii.TextureData.Alpha = alpha != null ? (RgbSpectrum) alpha : zero; ii.TextureData.Diffuse = ii.Color; ii.TextureData.Roughness = bump; ii.TextureData.Bump = bump; ii.TextureData.Medium = MediumInfo.Glass; ii.TextureData.Specular = (RgbSpectrum) reflectance; } } else { ii.Color = //matInfo.Kd; RgbSpectrum.Max(ref matInfo.Ks, ref matInfo.Kd); ii.TextureData = new SurfaceTextureData() { T0 = 0.5f, Transmittance = matInfo.Ks, Exponent = matInfo.Exponent, //Alpha = matInfo.Ka, Diffuse = matInfo.Kd, //Roughness = bump, //Bump = bump, Medium = MediumInfo.Glass, Specular = matInfo.Ks }; } /* if (mesh.MeshName.Equals("COL254_01", StringComparison.InvariantCultureIgnoreCase)) { //ii.Color = new RgbSpectrum(1f); ii.Normal = -scene.Triangles[currentTriangleIndex].ComputeNormal(scene.Vertices).Normalize(); //ii.ShadingNormal = ii.Normal; } */ ii.ShadingNormal = (Normal.Dot(ref PathRay.Dir, ref ii.Normal) > 0f) ? -ii.Normal : ii.Normal; if (options.Has(IntersectionOptions.ResolveSpectralDistributions)) { ii.Reflectance = ColorFactory.FromRgb(RgbSpectrum.Max(ref ii.Color, ref matInfo.Kd), SpectrumType.Reflectance); } //ii.ShadingNormal = ii.Normal; /* ii.Material = new DistributionBsdf(ii.Color.y(), ii.Color, new FresnelConductor(FresnelApproxEta(ref matInfo.Kd), FresnelApproxK(ref matInfo.Ks)) //new FresnelDielectric(1.5f, 1f) //new FresnelNoOP() ); new DistributionBsdf(bump.IsZero() ? ii.Color.Filter():bump.Avg(), ii.Color); * */ //new DistributionBsdf(bump.IsZero() ? ii.Color.Filter() : bump.Avg(), ii.Color); #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Surface sampling error"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); throw; } #endif }
public SurfaceIntersectionData GetIntersection(ref RayData PathRay, ref RayHit hit, IntersectionOptions flags) { var ii = new SurfaceIntersectionData(ref hit, false); EvalIntersectionAdvanced(ref PathRay, ref hit, ref ii, flags); return ii; }