// public virtual uint MethodReturn(uint arg) // { // object[] arr = { CurrentMethod, arg }; // WriteLine(_mt, TRACE_RETURN_GEN_FMT, arr); // return arg; // } // // public virtual ulong MethodReturn(ulong arg) // { // object[] arr = { CurrentMethod, arg }; // WriteLine(_mt, TRACE_RETURN_GEN_FMT, arr); // return arg; // } public virtual Traceable MethodReturn(Traceable arg) { object[] arr = { CurrentMethod, arg == null ? "null" : arg.TraceString }; WriteLine(_mt, TRACE_RETURN_GEN_FMT, arr); return(arg); }
/// <summary> /// Trace a ray and return the RGB color vector. /// </summary> /// <param name="ray">The current ray being traced.</param> /// <param name="objects">The collection of tracable objects.</param> /// <param name="lights">The collection of lights</param> /// <param name="eye">The eye vector</param> /// <returns>The RGB color vector3 if the ray hits an object, otherwise null.</returns> public static Color Trace(this Ray ray, IEnumerable <Traceable> objects, IEnumerable <Light> lights, Vector3 eye, Color ambientLight) { if (objects == null) { throw new ArgumentNullException(nameof(objects)); } if (lights == null) { throw new ArgumentNullException(nameof(lights)); } if (eye == null) { throw new ArgumentNullException(nameof(eye)); } float hit; float[] hits; float nearestHit = (float)Util.NearlyInfinite; Traceable nearestObject = null; foreach (var t in objects) { hits = t.Intersections(ray); if (hits.Any()) { hit = hits.First(); if (hit < nearestHit) { nearestHit = hit; nearestObject = t; } } } if (nearestObject == null) { return(Color.Black); } else { var normal = nearestObject.GetNormalAt(ray.PointAt(nearestHit)); var baseColor = nearestObject.GetBaseColorAt(ray.PointAt(nearestHit)) .ToVector(); var color = Vector3.Multiply(baseColor, ambientLight.ToVector()); Vector3 lightVector, lightColorVector, viewingVector, diffuseContribution, specularContribution, halfVector; float lDotN, hDotN; foreach (var l in lights) { lightVector = l.GetLightVector(ray.PointAt((float)nearestHit)); lightColorVector = l.Color.ToVector(); lDotN = Vector3.Dot(lightVector, normal); if (lDotN > 0) { // Diffuse light contribution diffuseContribution = Vector3.Multiply(Vector3.Multiply(baseColor, lightColorVector), lDotN); color = color + diffuseContribution; // Specular light contribution viewingVector = Vector3.Normalize(eye - nearestObject.Model.Origin.Image(ray.PointAt(nearestHit))); halfVector = Vector3.Normalize(viewingVector + lightVector); hDotN = Vector3.Dot(halfVector, normal); if (hDotN > 0) { specularContribution = Vector3.Multiply(Vector3.Multiply(nearestObject.SpecularColor.ToVector(), lightColorVector), (float)Math.Pow(hDotN, nearestObject.SpecularExponent)); color = color + specularContribution; } } } return(color.Clamp().ToColor()); } }
// public override uint MethodReturn(uint arg) // { // base.MethodReturn(arg); // PopCurrentMethod(); // return arg; // } // // public override ulong MethodReturn(ulong arg) // { // base.MethodReturn(arg); // PopCurrentMethod(); // return arg; // } public override Traceable MethodReturn(Traceable arg) { base.MethodReturn(arg); PopCurrentMethod(); return(arg); }
////////////////////////////////////////////////////////////// /// <summary> /// This method allows adding traceable contents via /// TraceString instead of ToString. /// </summary> /// <param name="traceable">the traceable instance</param> /// <returns>the StringBuilder reference</returns> ////////////////////////////////////////////////////////////// public StringBuilder Append(Traceable traceable) { return(_buf.Append(traceable.TraceString)); }