public static Cubic <SpanF> MultiplySpanByMatrix(Cubic <SpanF> span, Matrix4x4 mat) { SpanAPI.WeakTODO(); // slow but accurate way bool doAllCorners = false; if (doAllCorners) { var ans = span .Select(k => k.EachOfFromAndTo()) // seperate from and to .EachPermutation() // generate all corner permutations .Select(k => ToVector3(k)) .Select(k => mat.MultiplyPoint(k)) // transform by matrix .Select(k => k.ToCubic().Select(j => SpanAPI.spanExactly(j))) // back into spans .Aggregate((a, b) => a.Select2(b, (c, d) => SpanAPI.spanUnion(c, d))); // take union of all return(ans); } // only doing the corners, ideally do all: var cornerAM = ToVector3(span.Select(k => k.From)); var cornerBM = ToVector3(span.Select(k => k.To)); var cornerAW = mat.MultiplyPoint(cornerAM); var cornerBW = mat.MultiplyPoint(cornerBM); return(new Cubic <SpanF>( SpanAPI.spanUnsorted(cornerAW.x, cornerBW.x), SpanAPI.spanUnsorted(cornerAW.y, cornerBW.y), SpanAPI.spanUnsorted(cornerAW.z, cornerBW.z) )); }
public static SpanF exactly(double f) { return(SpanAPI.spanExactly(f)); }
private Color EvalFlowVolume(Vector3 center, float radius, Cubic <SpanF> modelPos) { float forces = 0.0f; float forceM = 0.0f; float chargeE = 0.008f; float chargeM = 0.014f; Vector3 flowDir = Vector3.zero; var centerQ = spanVectorFromUnity(center, radius); var torqueQ = spanVectorFromUnity(Vector3.zero, 0.0f); float flowVertRadius = 0.04f; float flowVertFwdRadius = 0.02f; var magTorqueCharge = SpanF.exactly(0.021); if (false) { var rv = modelPos.Y.times(SpanF.exactly(2.0)); var rc = SpanAPI.spanColorSignedToRGB(rv); var clr = new Color(rc.X, rc.Y, rc.Z, 0.9f); if (PreviousRY != rv.To) { Debug.Log("M/G: " + rv + " " + rc.Y); PreviousRY = rv.To; } return(clr); } if (true) { foreach (var fv in this.CachedFlowVerts) { var dist = (fv.Location - center).magnitude; var oneOverDistSqr = (1.0f / (dist * dist)); var fe = chargeE * oneOverDistSqr; if (false) { var locQ = spanVectorFromUnity(fv.Location, flowVertRadius); var fQ = spanVectorFromUnity(fv.ForwardDir, flowVertFwdRadius); var rQ = SpanAPI.spanVectorSubtract(centerQ, locQ); var cQ = SpanAPI.spanVectorCross(rQ, fQ); //var cQ = SpanAPI.spanVectorDot(rQ, fQ); var scQ = magTorqueCharge.times(SpanF.exactly(oneOverDistSqr)); cQ = SpanAPI.spanVectorScale(cQ, scQ); torqueQ = SpanAPI.spanVectorAdd(torqueQ, cQ); } var fm = chargeM * oneOverDistSqr * Vector3.Dot(fv.Location - center, -fv.ForwardDir); forces += fe; flowDir += fv.ForwardDir * fe; //forceM += fm; } } if (false) { var torqueMagQ = SpanAPI.spanVectorMagnitude(torqueQ); var rawVal = torqueMagQ; Debug.Log("Val = " + rawVal); //var toColorRangeOffset = SpanAPI.spanExactly (1.0); var toColorRangeScale = SpanAPI.spanExactly(1.0); //var rgb = torqueMagQ.add(toColorRangeOffset).times(toColorRangeScale).ToColorRGB (); var valInRange = rawVal.times(SpanAPI.spanExactly(2.0f / 2.6f)).add(SpanAPI.spanExactly(-1.0f)); var rgb = valInRange.ToColorRGB(); //rgb = new Cubic<float> (0, (float)SpanAPI.spanColorSignedForGreen (valInRange).To, 0); var alpha = rgb.Y; // Mathf.Max(Mathf.Max(rgb.X,rgb.Y),rgb.Z) * 0.5f; return(new Color(rgb.X, rgb.Y, rgb.Z, alpha)); } flowDir.y *= 10.0f; var yval = Mathf.Clamp01(Mathf.Abs(flowDir.normalized.y)); var dirColor = Color.Lerp(this.ColorX, this.ColorY, yval); var clearColor = this.ChakraColor; var fullColor = dirColor; //ColorWithAlpha (dirColor, 1.0f); return(Color.Lerp(clearColor, fullColor, Mathf.Clamp01(forces))); }
public IEnumerable <bool> UpdateMultiChakras() { this.MultiChakras = this.gameObject.transform.parent .GetComponentsInChildren <VolumeTextureBehavior>() //.Where(k => (k.IsAura)||(k.name.Contains("Solar"))).ToArray() ; List <Matrix4x4> worldToChakras = new List <Matrix4x4>(); foreach (var c in this.MultiChakras) { c.EnsureSetup(); worldToChakras.Add(c.transform.worldToLocalMatrix); } Debug.Log("MULTI CHAKRA from " + this.MultiChakras.Length + " children."); var m2w = this.transform.localToWorldMatrix; bool debugMe = true; var proj = SpanAPI.spanProjFromCubicDomainAndRange( mColorBuffer.Size.Select(k => SpanAPI.span(0, k - 1)), Cubic <SpanF> .CreateSame(SpanAPI.span(-0.5, 0.5)) ); var invProj = SpanAPI.spanProjFromCubicDomainAndRange( Cubic <SpanF> .CreateSame(SpanAPI.span(-0.5, 0.5)), mColorBuffer.Size.Select(k => SpanAPI.span(0, k - 1)) ); var invProjForMath = SpanAPI.spanProjFromCubicDomainAndRange( Cubic <SpanF> .CreateSame(SpanAPI.span(-0.5, 0.5)), Cubic <SpanF> .CreateSame(SpanAPI.span(-1.0, 1.0)) ); //var proj = SpanAPI.Example_SetupProjection (mColorBuffer.Size.X, mColorBuffer.Size.Y, mColorBuffer.Size.Z); //var invProj = SpanAPI.Example_SetupSignedUnitToIntProjection(mColorBuffer.Size.X, mColorBuffer.Size.Y, mColorBuffer.Size.Z); Color defaultVal = Color.clear; for (int i = 0; i < this.mColorBuffer.Length; i++) { var ndx = this.mColorBuffer.UnprojectIndex(i); var mpos = SpanAPI.spanProjCubicInt(proj, ndx); Color curColor = defaultVal; if (this.mColorBuffer.IsEdge(ndx)) { // it's an edge, ignore it } else { //foreach (var chakra in this.MultiChakras) for (int ci = 0; ci < this.MultiChakras.Length; ci++) { var chakra = this.MultiChakras[ci]; var w2c = worldToChakras[ci]; var cpos = MultiplySpanByMatrix(mpos, w2c * m2w);// m2w * w2c); //cpos = cpos.Select(k => SpanAPI.spanMult(k, SpanAPI.spanExactly(1.5))); if (MultiChakraFullEval && (!chakra.IsAura)) { var suSpan = SpanAPI.spanProjCubicSpan(invProjForMath, cpos); var suVal = chakra.ChakraFieldFromSignedUnit(suSpan); var suColor = chakra.ColorFromChakraField(suVal); curColor = MixColors(curColor, suColor); continue; } var fspan = SpanAPI.spanProjCubicSpan(invProj, cpos); fspan = fspan.Select(k => SpanAPI.spanMult(k, SpanAPI.spanExactly(1.01))); var ispan = fspan.Select(k => SpanI.FromSpanF(k)); var sample = chakra.mColorBuffer.SampleSpan(ispan, Color.clear, (a, b) => MixColors(a, b)); if (debugMe) { debugMe = false; Debug.Log("proj = " + proj); Debug.Log("invProj = " + invProj); Debug.Log("ndx = " + ndx); Debug.Log("mpos = " + mpos); var testInvPos = SpanAPI.spanProjCubicSpan(invProj, mpos); Debug.Log("testInvPos = " + testInvPos); var testISpan = testInvPos.Select(k => SpanI.FromSpanF(k)); Debug.Log("testISpan = " + testISpan); Debug.Log("mpos = " + mpos); Debug.Log("cpos = " + cpos); Debug.Log("fspan = " + fspan); Debug.Log("ispan = " + ispan); Debug.Log("sample = " + sample); } curColor = MixColors(curColor, sample); } } this.mColorBuffer.Write(ndx, curColor); if (((i % 100)) == 99) { this.UpdateTextureFromBuffer(); yield return(false); } } //return; this.UpdateTextureFromBuffer(); this.TrySaveToCache(); Debug.Log("MULTI CHAKRAS UPDATED!"); }