public static Unity.Mathematics.float3 stereographicProjection(Unity.Mathematics.float4 pos) { //then inflate each vert to the edge of the sphere and keep that value. pos = pos / IMRE.Math.Operations.magnitude(pos); //TODO turn to make north pole float4.right // IMRE.Math.HigherDimensionsMaths.rotate(pos, new UnityEngine.Vector4(1, 0, 0, 0), // IMRE.ScaleDimension.SpencerStudyControl.ins.NorthPole, // IMRE.Math.Operations.Angle(new UnityEngine.Vector4(1, 0, 0, 0), // IMRE.ScaleDimension.SpencerStudyControl.ins.NorthPole)); //take stereographic projection in a given direction. //this assumes that the north pole is in the (x) direction. //from wikipedia float denom = 1 - pos.x; //result needs sums across y,z,w. Map onto x,y,z in UntiySpace. Unity.Mathematics.float3 result = new float3(UnityEngine.Mathf.Pow(pos.y / denom, 2), UnityEngine.Mathf.Pow(pos.z / denom, 2), UnityEngine.Mathf.Pow(pos.w / denom, 2)); //TODO turn to restore north //HigherDimensionsMaths.rotate(result, new Vector4(1, 0, 0, 0), // IMRE.ScaleDimension.SpencerStudyControl.ins.NorthPole, // -1f*Operations.Angle(new Vector4(1, 0, 0, 0), IMRE.ScaleDimension.SpencerStudyControl.ins.NorthPole)); return(result); }
private static void Vector4Cosin(ref Vector4 input, Vector4 a, Vector4 b) { input.x = Cosine(a.x + b.x); input.y = Cosine(a.y + b.y); input.z = Cosine(a.z + b.z); input.w = Cosine(a.w + b.w); }
private static Vector4 MultiplyVec4(Vector4 a, Vector4 b) { #if MATHEMATICS return(a * b); #else return(Vector4.Scale(a, b)); #endif }
private static float Dot4(Vector4 a, Vector4 b) { #if MATHEMATICS return(dot(a, b)); #else return(Vector4.Dot(a, b)); #endif }
private static Unity.Mathematics.float4[] GetRange(this Unity.Mathematics.float4[] v, int start, int end) { Unity.Mathematics.float4[] result = new Unity.Mathematics.float4[end - start]; int length = System.Math.Min(v.Length, end - start); for (int i = 0; i < length; i++) { result[i] = v[i + start]; } return(result); }
public static Unity.Mathematics.float3 parallelProjection(Unity.Mathematics.float4 tmpVert) { Unity.Mathematics.float4 planePos = IMRE.ScaleDimension.SpencerStudyControl.ins.hyperPlane; Unity.Mathematics.float4 planeNormal = IMRE.ScaleDimension.SpencerStudyControl.ins.hyperPlaneNormal; Unity.Mathematics.float4 pos = tmpVert - IMRE.Math.HigherDimensionsMaths.project(tmpVert - planePos, planeNormal); //this basis system might be unstable as the axis is moved. Consider defining axis by basis. Unity.Mathematics.float4x3 basis = IMRE.Math.HigherDimensionsMaths.basisSystem(planeNormal); return(new Unity.Mathematics.float3(UnityEngine.Vector4.Dot(pos, basis.c0), UnityEngine.Vector4.Dot(pos, basis.c1), UnityEngine.Vector4.Dot(pos, basis.c2))); }
bool PlaneRaycast(vec3 ro, vec3 rd, vec4 plane, out float distance) { #if USE_BURST_AND_MATH float a = dot(rd, plane.xyz); float num = -dot(ro, plane.xyz) - plane.w; #else float a = dot(rd, plane); float num = -dot(ro, plane) - plane.w; #endif if (abs(a) < EPSILON) { distance = 0.0f; return(false); } distance = num / a; return(distance > 0.0); }
public static Unity.Mathematics.float3 projectPosition(Unity.Mathematics.float4 pos) { switch (IMRE.ScaleDimension.SpencerStudyControl.ins.projectionMethod) { case IMRE.Math.ProjectionMethod.stereographic: return(stereographicProjection(pos)); case IMRE.Math.ProjectionMethod.projective: return(projectiveProjection(pos)); case IMRE.Math.ProjectionMethod.parallel: return(parallelProjection(pos)); default: UnityEngine.Debug.LogWarning("Failed to Project, Method not Implemented"); return(Unity.Mathematics.float3.zero); } }
// Start is called before the first frame update void Start() { Unity.Mathematics.float4 a = fiveCellVertices[0]; Unity.Mathematics.float4 b = fiveCellVertices[1]; Unity.Mathematics.float4 c = fiveCellVertices[2]; Unity.Mathematics.float4 d = fiveCellVertices[3]; Unity.Mathematics.float4 e = fiveCellVertices[4]; Unity.Mathematics.float4[] pyrmaid1 = { a, b, c, d }; Unity.Mathematics.float4[] pyrmaid2 = { a, b, d, e }; Unity.Mathematics.float4[] pyrmaid3 = { a, c, d, e }; Unity.Mathematics.float4[] pyrmaid4 = { b, c, d, e }; BuildTetrahedron(pyrmaid1, planePos, planeNormal); BuildTetrahedron(pyrmaid2, planePos, planeNormal); BuildTetrahedron(pyrmaid3, planePos, planeNormal); BuildTetrahedron(pyrmaid4, planePos, planeNormal); }
private void UpdateTriangles() { Unity.Mathematics.float4 a = fiveCellVertices[0]; Unity.Mathematics.float4 b = fiveCellVertices[1]; Unity.Mathematics.float4 c = fiveCellVertices[2]; Unity.Mathematics.float4 d = fiveCellVertices[3]; Unity.Mathematics.float4 e = fiveCellVertices[4]; Unity.Mathematics.float4[] pyrmaid1 = { a, b, c, d }; Unity.Mathematics.float4[] pyrmaid2 = { a, b, d, e }; Unity.Mathematics.float4[] pyrmaid3 = { a, c, d, e }; Unity.Mathematics.float4[] pyrmaid4 = { b, c, d, e }; pyramidXC.ForEach(p => p.planePos = planePos); pyramidXC.ForEach(p => p.planeNormal = planeNormal); //TODO project verticies down a dimension. //pyramidXC[0].tetrahderonVertices = pyrmaid1; //pyramidXC[1].tetrahderonVertices = pyrmaid2; //pyramidXC[2].tetrahderonVertices = pyrmaid3; //pyramidXC[3].tetrahderonVertices = pyrmaid4; }
public static Unity.Mathematics.float3 projectiveProjection(Unity.Mathematics.float4 tmpVert) { Unity.Mathematics.float4 origin = IMRE.ScaleDimension.SpencerStudyControl.ins.origin; Unity.Mathematics.float4 planePos = IMRE.ScaleDimension.SpencerStudyControl.ins.hyperPlane; Unity.Mathematics.float4 planeNormal = IMRE.ScaleDimension.SpencerStudyControl.ins.hyperPlaneNormal; Unity.Mathematics.float4 dir = (tmpVert - origin) / IMRE.Math.Operations.magnitude(tmpVert - origin); float4 pos = Operations.SegmentPlaneIntersection(origin, tmpVert, planePos, planeNormal); /* //normalized direction * Unity.Mathematics.float4 projOnPlane = * tmpVert - IMRE.Math.HigherDimensionsMaths.project(tmpVert - planePos, planeNormal); * //TODO consider if mathf.cos takes an absolute value here * float diff = IMRE.Math.Operations.magnitude(tmpVert - projOnPlane) / * UnityEngine.Mathf.Cos(IMRE.Math.Operations.Angle(planeNormal, dir)); * Unity.Mathematics.float4 pos = tmpVert + diff * dir;*/ //this basis system might be unstable as the axis is moved. Consider defining axis by basis. Unity.Mathematics.float4x3 basis = IMRE.Math.HigherDimensionsMaths.basisSystem(planeNormal); return(new Unity.Mathematics.float3(UnityEngine.Vector4.Dot(pos, basis.c0), UnityEngine.Vector4.Dot(pos, basis.c1), UnityEngine.Vector4.Dot(pos, basis.c2))); }
//explicit version of subdivide function private static void subdivideVerts(ref Unity.Mathematics.float4[] verts, ref int[] tris) { //store old values in temporary locations float4[] oldVerts = new float4[verts.Length]; int[] oldTris = new int[tris.Length]; verts.CopyTo(oldVerts, 0); tris.CopyTo(oldTris, 0); //store new values here. int oldTriCount = oldTris.Length / 3; tris = new int[oldTriCount * 12]; verts = new Unity.Mathematics.float4[verts.Length == 3 ? 6 : verts.Length * 4]; for (int i = 0; i < oldTriCount; i++) { int[] newTri = newTriangle(i * 6); float4[] oldVertsSubSet = { oldVerts[oldTris[i * 3]], oldVerts[oldTris[i * 3 + 1]], oldVerts[oldTris[i * 3 + 2]] }; float4[] newVerts = MeshOperations.newVerts(oldVertsSubSet); newTri.CopyTo(tris, i * 12); newVerts.CopyTo(verts, i * 6); } }
public static float4 smoothstep(float4 a, float4 b, float4 x) { var t = saturate((x - a) / (b - a)); return(t * t * (3.0F - (2.0F * t))); }
/// <summary> /// Classic Perlin noise /// </summary> /// <param name="P">Point on a 4D grid of gradient vectors.</param> /// <returns>Noise value.</returns> public static float cnoise(float4 P) { float4 Pi0 = floor(P); // Integer part for indexing float4 Pi1 = Pi0 + 1.0f; // Integer part + 1 Pi0 = mod289(Pi0); Pi1 = mod289(Pi1); float4 Pf0 = frac(P); // Fractional part for interpolation float4 Pf1 = Pf0 - 1.0f; // Fractional part - 1.0 float4 ix = float4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); float4 iy = float4(Pi0.yy, Pi1.yy); float4 iz0 = float4(Pi0.zzzz); float4 iz1 = float4(Pi1.zzzz); float4 iw0 = float4(Pi0.wwww); float4 iw1 = float4(Pi1.wwww); float4 ixy = permute(permute(ix) + iy); float4 ixy0 = permute(ixy + iz0); float4 ixy1 = permute(ixy + iz1); float4 ixy00 = permute(ixy0 + iw0); float4 ixy01 = permute(ixy0 + iw1); float4 ixy10 = permute(ixy1 + iw0); float4 ixy11 = permute(ixy1 + iw1); float4 gx00 = ixy00 * (1.0f / 7.0f); float4 gy00 = floor(gx00) * (1.0f / 7.0f); float4 gz00 = floor(gy00) * (1.0f / 6.0f); gx00 = frac(gx00) - 0.5f; gy00 = frac(gy00) - 0.5f; gz00 = frac(gz00) - 0.5f; float4 gw00 = float4(0.75f) - abs(gx00) - abs(gy00) - abs(gz00); float4 sw00 = step(gw00, float4(0.0f)); gx00 -= sw00 * (step(0.0f, gx00) - 0.5f); gy00 -= sw00 * (step(0.0f, gy00) - 0.5f); float4 gx01 = ixy01 * (1.0f / 7.0f); float4 gy01 = floor(gx01) * (1.0f / 7.0f); float4 gz01 = floor(gy01) * (1.0f / 6.0f); gx01 = frac(gx01) - 0.5f; gy01 = frac(gy01) - 0.5f; gz01 = frac(gz01) - 0.5f; float4 gw01 = float4(0.75f) - abs(gx01) - abs(gy01) - abs(gz01); float4 sw01 = step(gw01, float4(0.0f)); gx01 -= sw01 * (step(0.0f, gx01) - 0.5f); gy01 -= sw01 * (step(0.0f, gy01) - 0.5f); float4 gx10 = ixy10 * (1.0f / 7.0f); float4 gy10 = floor(gx10) * (1.0f / 7.0f); float4 gz10 = floor(gy10) * (1.0f / 6.0f); gx10 = frac(gx10) - 0.5f; gy10 = frac(gy10) - 0.5f; gz10 = frac(gz10) - 0.5f; float4 gw10 = float4(0.75f) - abs(gx10) - abs(gy10) - abs(gz10); float4 sw10 = step(gw10, float4(0.0f)); gx10 -= sw10 * (step(0.0f, gx10) - 0.5f); gy10 -= sw10 * (step(0.0f, gy10) - 0.5f); float4 gx11 = ixy11 * (1.0f / 7.0f); float4 gy11 = floor(gx11) * (1.0f / 7.0f); float4 gz11 = floor(gy11) * (1.0f / 6.0f); gx11 = frac(gx11) - 0.5f; gy11 = frac(gy11) - 0.5f; gz11 = frac(gz11) - 0.5f; float4 gw11 = float4(0.75f) - abs(gx11) - abs(gy11) - abs(gz11); float4 sw11 = step(gw11, float4(0.0f)); gx11 -= sw11 * (step(0.0f, gx11) - 0.5f); gy11 -= sw11 * (step(0.0f, gy11) - 0.5f); float4 g0000 = float4(gx00.x, gy00.x, gz00.x, gw00.x); float4 g1000 = float4(gx00.y, gy00.y, gz00.y, gw00.y); float4 g0100 = float4(gx00.z, gy00.z, gz00.z, gw00.z); float4 g1100 = float4(gx00.w, gy00.w, gz00.w, gw00.w); float4 g0010 = float4(gx10.x, gy10.x, gz10.x, gw10.x); float4 g1010 = float4(gx10.y, gy10.y, gz10.y, gw10.y); float4 g0110 = float4(gx10.z, gy10.z, gz10.z, gw10.z); float4 g1110 = float4(gx10.w, gy10.w, gz10.w, gw10.w); float4 g0001 = float4(gx01.x, gy01.x, gz01.x, gw01.x); float4 g1001 = float4(gx01.y, gy01.y, gz01.y, gw01.y); float4 g0101 = float4(gx01.z, gy01.z, gz01.z, gw01.z); float4 g1101 = float4(gx01.w, gy01.w, gz01.w, gw01.w); float4 g0011 = float4(gx11.x, gy11.x, gz11.x, gw11.x); float4 g1011 = float4(gx11.y, gy11.y, gz11.y, gw11.y); float4 g0111 = float4(gx11.z, gy11.z, gz11.z, gw11.z); float4 g1111 = float4(gx11.w, gy11.w, gz11.w, gw11.w); float4 norm00 = taylorInvSqrt(float4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); g0000 *= norm00.x; g0100 *= norm00.y; g1000 *= norm00.z; g1100 *= norm00.w; float4 norm01 = taylorInvSqrt(float4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); g0001 *= norm01.x; g0101 *= norm01.y; g1001 *= norm01.z; g1101 *= norm01.w; float4 norm10 = taylorInvSqrt(float4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); g0010 *= norm10.x; g0110 *= norm10.y; g1010 *= norm10.z; g1110 *= norm10.w; float4 norm11 = taylorInvSqrt(float4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); g0011 *= norm11.x; g0111 *= norm11.y; g1011 *= norm11.z; g1111 *= norm11.w; float n0000 = dot(g0000, Pf0); float n1000 = dot(g1000, float4(Pf1.x, Pf0.yzw)); float n0100 = dot(g0100, float4(Pf0.x, Pf1.y, Pf0.zw)); float n1100 = dot(g1100, float4(Pf1.xy, Pf0.zw)); float n0010 = dot(g0010, float4(Pf0.xy, Pf1.z, Pf0.w)); float n1010 = dot(g1010, float4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); float n0110 = dot(g0110, float4(Pf0.x, Pf1.yz, Pf0.w)); float n1110 = dot(g1110, float4(Pf1.xyz, Pf0.w)); float n0001 = dot(g0001, float4(Pf0.xyz, Pf1.w)); float n1001 = dot(g1001, float4(Pf1.x, Pf0.yz, Pf1.w)); float n0101 = dot(g0101, float4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); float n1101 = dot(g1101, float4(Pf1.xy, Pf0.z, Pf1.w)); float n0011 = dot(g0011, float4(Pf0.xy, Pf1.zw)); float n1011 = dot(g1011, float4(Pf1.x, Pf0.y, Pf1.zw)); float n0111 = dot(g0111, float4(Pf0.x, Pf1.yzw)); float n1111 = dot(g1111, Pf1); float4 fade_xyzw = fade(Pf0); float4 n_0w = lerp(float4(n0000, n1000, n0100, n1100), float4(n0001, n1001, n0101, n1101), fade_xyzw.w); float4 n_1w = lerp(float4(n0010, n1010, n0110, n1110), float4(n0011, n1011, n0111, n1111), fade_xyzw.w); float4 n_zw = lerp(n_0w, n_1w, fade_xyzw.z); float2 n_yzw = lerp(n_zw.xy, n_zw.zw, fade_xyzw.y); float n_xyzw = lerp(n_yzw.x, n_yzw.y, fade_xyzw.x); return(2.2f * n_xyzw); }
public float4x2(uint4x2 v) { this.c0 = v.c0; this.c1 = v.c1; }
public quaternion(float4 value) { this.value = value; }
public float4x2(bool4x2 v) { this.c0 = math.select(new float4(0.0f), new float4(1.0f), v.c0); this.c1 = math.select(new float4(0.0f), new float4(1.0f), v.c1); }
public static float lengthSquared(float4 v) { return(dot(v, v)); }
public static bool any(float4 a) { return(a.x != 0.0F || a.y != 0.0F || a.z != 0.0F || a.w != 0.0F); }
public float4x2(double4x2 v) { this.c0 = (float4)v.c0; this.c1 = (float4)v.c1; }
public float4x2(double v) { this.c0 = (float4)v; this.c1 = (float4)v; }
/// <summary> /// Given a position in world-space, returns the wave height and normal /// </summary> /// <param name="position">Sample position in world-space</param> /// <param name="waterMat">Material using StylizedWater2 shader</param> /// <param name="waterLevel">Height of the reference water plane.</param> /// <param name="rollStrength">Multiplier for the the normal strength</param> /// <param name="dynamicMaterial">If true, the material's wave parameters will be re-fetched with every function call</param> /// <param name="normal">Output upwards normal vector, perpendicular to the wave</param> /// <returns>Wave height, in world-space.</returns> public static float SampleWaves(UnityEngine.Vector3 position, Material waterMat, float waterLevel, float rollStrength, bool dynamicMaterial, out UnityEngine.Vector3 normal) { Profiler.BeginSample("Buoyancy sampling"); if (!waterMat) { normal = UnityEngine.Vector3.up; return(waterLevel); } //Fetch the material's wave parameters, so the exact calculations can be mirrored if (lastMaterial == null || lastMaterial.Equals(waterMat) == false) { GetMaterialParameters(waterMat); lastMaterial = waterMat; } if (dynamicMaterial || !Application.isPlaying) { GetMaterialParameters(waterMat); } Vector4 freq = new Vector4(1.3f, 1.35f, 1.25f, 1.25f) * (1 - waveParameters.distance) * 3f; direction1 = MultiplyVec4(dir1, waveParameters.direction); direction2 = MultiplyVec4(dir2, waveParameters.direction); Vector3 offsets = Vector3.zero; frequency = freq; realSpeed.x *= waveParameters.animationParams.x; realSpeed.y *= waveParameters.animationParams.y; realSpeed.z *= waveParameters.animationParams.x; realSpeed.w *= waveParameters.animationParams.y; for (int i = 0; i <= waveParameters.count; i++) { float t = 1f + ((float)i / (float)waveParameters.count); frequency *= t; AB.x = steepness.x * waveParameters.steepness * direction1.x * amp.x; AB.y = steepness.x * waveParameters.steepness * direction1.y * amp.x; AB.z = steepness.x * waveParameters.steepness * direction1.z * amp.y; AB.w = steepness.x * waveParameters.steepness * direction1.w * amp.y; CD.x = steepness.z * waveParameters.steepness * direction2.x * amp.z; CD.y = steepness.z * waveParameters.steepness * direction2.y * amp.z; CD.z = steepness.w * waveParameters.steepness * direction2.z * amp.w; CD.w = steepness.w * waveParameters.steepness * direction2.w * amp.w; planarPosition.x = position.x; planarPosition.y = position.z; #if MATHEMATICS dotABCD.x = Dot2(direction1.xy, planarPosition) * frequency.x; dotABCD.y = Dot2(direction1.zw, planarPosition) * frequency.y; dotABCD.z = Dot2(direction2.xy, planarPosition) * frequency.z; dotABCD.w = Dot2(direction2.zw, planarPosition) * frequency.w; #else dotABCD.x = Dot2(new Vector2(direction1.x, direction1.y), planarPosition) * frequency.x; dotABCD.y = Dot2(new Vector2(direction1.z, direction1.w), planarPosition) * frequency.y; dotABCD.z = Dot2(new Vector2(direction2.x, direction2.y), planarPosition) * frequency.z; dotABCD.w = Dot2(new Vector2(direction2.z, direction2.w), planarPosition) * frequency.w; #endif TIME = (_TimeParameters * waveParameters.animationParams.z * waveParameters.speed * speed); sine.x = Sine(dotABCD.x + TIME.x); sine.y = Sine(dotABCD.y + TIME.y); sine.z = Sine(dotABCD.z + TIME.z); sine.w = Sine(dotABCD.w + TIME.w); cosine.x = Cosine(dotABCD.x + TIME.x); cosine.y = Cosine(dotABCD.y + TIME.y); cosine.z = Cosine(dotABCD.z + TIME.z); cosine.w = Cosine(dotABCD.w + TIME.w); offsets.x += Dot4(cosine, new Vector4(AB.x, AB.z, CD.x, CD.z)); offsets.y += Dot4(sine, amp); offsets.z += Dot4(cosine, new Vector4(AB.y, AB.w, CD.y, CD.w)); } rollStrength *= Mathf.Lerp(0.001f, 0.1f, waveParameters.steepness); normal = new Vector3(-offsets.x * rollStrength * waveParameters.height, 2f, -offsets.z * rollStrength * waveParameters.height); #if MATHEMATICS normal = normalize(normal); #else normal = normal.normalized; #endif //Average height offsets.y /= waveParameters.count; Profiler.EndSample(); return((offsets.y * waveParameters.height) + waterLevel); }
public static float distance(float4 pt1, float4 pt2) { return(length(pt2 - pt1)); }
public float4x2(uint v) { this.c0 = v; this.c1 = v; }
public float4x2(float4 c0, float4 c1) { this.c0 = c0; this.c1 = c1; }
public static quaternion quaternion(float4 value) { return(new quaternion(value)); }
public float4x2(float v) { this.c0 = v; this.c1 = v; }
public static float4x2 float4x2(float4 c0, float4 c1) { return(new float4x2(c0, c1)); }
public void Bake(int raySamples, List <Renderer> renderers, Action <SDFVolume, float[], float, object> bakeComplete, object passthrough = null) { onBakeComplete = bakeComplete; int progressInterval = _settings.CellCount / 4; int progress = 0; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); vec3 halfVoxel = _settings.HalfVoxel; float maxDistance = 0f; //adjusted to best timings from testing but it could vary by CPU int calcRayLengthBatchCount = 32; calcRayLengthBatchCount = Mathf.Clamp(calcRayLengthBatchCount, 1, raySamples); int raycastBatchCount = 8; raycastBatchCount = Mathf.Clamp(raycastBatchCount, 1, raySamples); int prepareRaysBatchCount = 64; prepareRaysBatchCount = Mathf.Clamp(prepareRaysBatchCount, 1, raySamples); int compareBatchCount = 128; //for raycast method front facing geo and flipped backfacing geo is required List <Collider> geoFront = new List <Collider>(); List <Collider> geoBack = new List <Collider>(); CreateColliders(ref renderers, ref geoFront, ref geoBack); //prepare data NativeArray <float> distances = new NativeArray <float>(_settings.CellCount, Allocator.TempJob); NativeArray <CellResults> allResults = new NativeArray <CellResults>(_settings.CellCount, Allocator.TempJob); //constant for all cells NativeArray <vec3> sphereSamples = new NativeArray <vec3>(raySamples, Allocator.TempJob); //NativeArray<vec3> randomDirections = new NativeArray<vec3>(raySamples, Allocator.TempJob); NativeArray <vec4> volumePlanes = new NativeArray <vec4>(6, Allocator.TempJob); GetUniformPointsOnSphereNormalized(ref sphereSamples); //GetRandomDirections( _halfVoxel*settings.JitterScale, settings.JitterSeed, ref randomDirections); vec3 aabbMin = BoundsWorldAABB.min; vec3 aabbMax = BoundsWorldAABB.max; //the max ray length, used to normalize all resulting distances //so they are treated as 0 to 1 within a volume float aabbMagnitude = BoundsWorldAABB.size.magnitude; Plane pl = new Plane(Vector3.right, aabbMin); Plane pr = new Plane(Vector3.left, aabbMax); Plane pd = new Plane(Vector3.up, aabbMin); Plane pu = new Plane(Vector3.down, aabbMax); Plane pb = new Plane(Vector3.forward, aabbMin); Plane pf = new Plane(Vector3.back, aabbMax); volumePlanes[0] = new vec4(pl.normal.x, pl.normal.y, pl.normal.z, pl.distance); volumePlanes[1] = new vec4(pr.normal.x, pr.normal.y, pr.normal.z, pr.distance); volumePlanes[2] = new vec4(pd.normal.x, pd.normal.y, pd.normal.z, pd.distance); volumePlanes[3] = new vec4(pu.normal.x, pu.normal.y, pu.normal.z, pu.distance); volumePlanes[4] = new vec4(pb.normal.x, pb.normal.y, pb.normal.z, pb.distance); volumePlanes[5] = new vec4(pf.normal.x, pf.normal.y, pf.normal.z, pf.distance); //iterate each cell performing raycasted samples for (int i = 0; i < _settings.CellCount; i++) { #if UNITY_EDITOR if (i % progressInterval == 0) { EditorUtility.DisplayProgressBar(strProgressTitle, strProgress, i / (float)_settings.CellCount); } #endif vec3 positionWS = _settings.ToPositionWS(i, LocalToWorldNoScale); vec3 centerVoxelWS = positionWS + halfVoxel; NativeArray <float> rayLengths = new NativeArray <float>(raySamples, Allocator.TempJob); NativeArray <RaycastCommand> allRaycastsFront = new NativeArray <RaycastCommand>(raySamples, Allocator.TempJob); NativeArray <RaycastCommand> allRaycastsBack = new NativeArray <RaycastCommand>(raySamples, Allocator.TempJob); NativeArray <RaycastHit> frontHits = new NativeArray <RaycastHit>(raySamples, Allocator.TempJob); NativeArray <RaycastHit> backHits = new NativeArray <RaycastHit>(raySamples, Allocator.TempJob); //calculate the ray lengths, just so rays are clipped within the volume when raycasting CalculateRayLengths calcRayLengths = new CalculateRayLengths { Samples = sphereSamples, VolumePlanes = volumePlanes, RayLengths = rayLengths, RayLength = aabbMagnitude, RayOrigin = centerVoxelWS }; JobHandle rayLengthHandle = calcRayLengths.Schedule(raySamples, calcRayLengthBatchCount); //prepare raycasts front PrepareRaycastCommands frontPrc = new PrepareRaycastCommands { Samples = sphereSamples, RayLengths = rayLengths, LayerMask = LAYER_MASK_FRONT, Raycasts = allRaycastsFront, RayOrigin = centerVoxelWS, }; //prepare raycasts back PrepareRaycastCommands backPrc = new PrepareRaycastCommands { Samples = sphereSamples, RayLengths = rayLengths, LayerMask = LAYER_MASK_BACK, Raycasts = allRaycastsBack, RayOrigin = centerVoxelWS, }; //schedule front raycasts JobHandle prepareFrontHandle = frontPrc.Schedule( raySamples, prepareRaysBatchCount, rayLengthHandle); JobHandle scheduleFrontHandle = RaycastCommand.ScheduleBatch( allRaycastsFront, frontHits, raycastBatchCount, prepareFrontHandle); //schedule back raycasts JobHandle prepareBackHandle = backPrc.Schedule( raySamples, prepareRaysBatchCount, rayLengthHandle); JobHandle scheduleBackHandle = RaycastCommand.ScheduleBatch( allRaycastsBack, backHits, raycastBatchCount, prepareBackHandle); //combine handles JobHandle frontBackHandle = JobHandle.CombineDependencies(scheduleFrontHandle, scheduleBackHandle); //process results and put into current cell index ProcessHits processHits = new ProcessHits { FrontHits = frontHits, BackHits = backHits, Results = allResults.Slice(i, 1), }; JobHandle cellHandle = processHits.Schedule(frontBackHandle); cellHandle.Complete(); rayLengths.Dispose(); allRaycastsFront.Dispose(); allRaycastsBack.Dispose(); frontHits.Dispose(); backHits.Dispose(); } //for each cell //final distances CompareDistances compareDistances = new CompareDistances { Distances = distances, Results = allResults }; JobHandle compareDistancesHandle = compareDistances.Schedule(_settings.CellCount, compareBatchCount); compareDistancesHandle.Complete(); stopwatch.Stop(); Debug.Log("SDF bake completed in " + stopwatch.Elapsed.ToString("mm\\:ss\\.ff")); #if UNITY_EDITOR EditorUtility.ClearProgressBar(); #endif float[] distancesOut = new float[_settings.CellCount]; distances.CopyTo(distancesOut); //cleanup all the temp arrays distances.Dispose(); allResults.Dispose(); sphereSamples.Dispose(); //randomDirections.Dispose(); volumePlanes.Dispose(); foreach (var c in geoFront) { Object.DestroyImmediate(c.gameObject); } foreach (var c in geoBack) { Object.DestroyImmediate(c.gameObject); } //NOTE do not use max distance, instead use aabbMagnitude so distance fields are interchangeable bakeComplete?.Invoke(this, distancesOut, aabbMagnitude, passthrough); }
public static float length(float4 v) { return(sqrt(dot(v, v))); }