Exemple #1
0
        private void Start()
        {
            transform.position = UnityEngine.Vector3.zero;

            //take vertices and organize them into clockwise triangles to be passed to triangle intersection function
            Unity.Mathematics.float3 a = tetrahderonVertices[0];
            Unity.Mathematics.float3 b = tetrahderonVertices[1];
            Unity.Mathematics.float3 c = tetrahderonVertices[2];
            Unity.Mathematics.float3 d = tetrahderonVertices[3];

            Unity.Mathematics.float3x3 triangle1 = new Unity.Mathematics.float3x3(a, b, c);
            Unity.Mathematics.float3x3 triangle2 = new Unity.Mathematics.float3x3(a, c, d);
            Unity.Mathematics.float3x3 triangle3 = new Unity.Mathematics.float3x3(a, d, b);
            Unity.Mathematics.float3x3 triangle4 = new Unity.Mathematics.float3x3(b, c, d);

            triXC = new System.Collections.Generic.List <TriangleCrossSection>();
            BuildTriangle(triangle1, planePos, planeNormal);
            BuildTriangle(triangle2, planePos, planeNormal);
            BuildTriangle(triangle3, planePos, planeNormal);
            BuildTriangle(triangle4, planePos, planeNormal);

            gameObject.AddComponent <UnityEngine.MeshRenderer>();
            gameObject.AddComponent <UnityEngine.MeshFilter>();
            gameObject.GetComponent <MeshRenderer>().material = mat;
        }
Exemple #2
0
            public void Execute(int index)
            {
                vec3 rd = Samples[index];
                vec3 ro = RayOrigin;

                Raycasts[index] = new RaycastCommand(ro, rd, RayLengths[index], LayerMask);
            }
        private void updateSquares()
        {
            Unity.Mathematics.float3 a = cubeVertices[0];
            Unity.Mathematics.float3 b = cubeVertices[1];
            Unity.Mathematics.float3 c = cubeVertices[2];
            Unity.Mathematics.float3 d = cubeVertices[3];
            Unity.Mathematics.float3 e = cubeVertices[4];
            Unity.Mathematics.float3 f = cubeVertices[5];
            Unity.Mathematics.float3 g = cubeVertices[6];
            Unity.Mathematics.float3 h = cubeVertices[7];

            float3x4 square1 = new float3x4(a, b, c, d);
            float3x4 square2 = new float3x4(e, f, g, h);
            float3x4 square3 = new float3x4(d, c, g, h);
            float3x4 square4 = new float3x4(b, a, e, f);
            float3x4 square5 = new float3x4(c, b, f, g);
            float3x4 square6 = new float3x4(a, d, h, e);

            squareXC.ForEach(p => p.planePos    = planePos);
            squareXC.ForEach(p => p.planeNormal = planeNormal);

            squareXC[0].squareVertices = square1;
            squareXC[1].squareVertices = square2;
            squareXC[2].squareVertices = square3;
            squareXC[3].squareVertices = square4;
            squareXC[4].squareVertices = square5;
            squareXC[5].squareVertices = square6;
        }
        private void Start()
        {
            transform.position = Vector3.zero;

            //using same orientation as cross section function
            Unity.Mathematics.float3 a = cubeVertices[0];
            Unity.Mathematics.float3 b = cubeVertices[1];
            Unity.Mathematics.float3 c = cubeVertices[2];
            Unity.Mathematics.float3 d = cubeVertices[3];
            Unity.Mathematics.float3 e = cubeVertices[4];
            Unity.Mathematics.float3 f = cubeVertices[5];
            Unity.Mathematics.float3 g = cubeVertices[6];
            Unity.Mathematics.float3 h = cubeVertices[7];

            float3x4 square1 = new float3x4(a, b, c, d);
            float3x4 square2 = new float3x4(e, f, g, h);
            float3x4 square3 = new float3x4(d, c, g, h);
            float3x4 square4 = new float3x4(b, a, e, f);
            float3x4 square5 = new float3x4(c, b, f, g);
            float3x4 square6 = new float3x4(a, d, h, e);

            squareXC = new List <SquareCrossSection>();
            BuildSquare(square1, planePos, planeNormal);
            BuildSquare(square2, planePos, planeNormal);
            BuildSquare(square3, planePos, planeNormal);
            BuildSquare(square4, planePos, planeNormal);
            BuildSquare(square5, planePos, planeNormal);
            BuildSquare(square6, planePos, planeNormal);

            gameObject.AddComponent <MeshRenderer>();
            gameObject.AddComponent <MeshFilter>();
            gameObject.GetComponent <MeshRenderer>().material = mat;
        }
Exemple #5
0
        public unsafe void RigidBodyCalculateDistancePointTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;

            var queryPos = new float3(-10, -10, -10);

            rigidbody.Collider = (Collider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            var pointDistanceInput = new PointDistanceInput();

            pointDistanceInput.Position = queryPos;
            pointDistanceInput.Filter   = CollisionFilter.Default;

            var closestHit = new DistanceHit();
            var allHits    = new NativeList <DistanceHit>(Allocator.Temp);

            // OK case : with enough max distance
            pointDistanceInput.MaxDistance = 10000.0f;
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput));
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput, out closestHit));
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput, ref allHits));

            // Fail case : not enough max distance
            pointDistanceInput.MaxDistance = 1;
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput));
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput, out closestHit));
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput, ref allHits));
        }
Exemple #6
0
        public static void projectTriangle(Unity.Mathematics.float4[] verts, int subdiv,
                                           out Unity.Mathematics.float3[] out_verts, out int[] out_tris,
                                           IMRE.Math.ProjectionMethod method)
        {
            //break triangle into smaller triangles
            //use a modified Sierpiński triangle as a division mechanic (partition every triangle into 3 triangles each round). Then there are always 3^n triangles
            out_tris = new[] { 0, 1, 2 };
            //loop subdiv times on subdivide verts.
            //subdivide verts calls itself, but should terminate when it reaches a case where the size of a partition is 3.

            /*
             * Case 1 - triangle of 3 verticies - split into 6 (hit else case)
             * Case 2 - 6 verts - split in half (two of 3).  round 2, hit else case.
             * Case 3 - 12 verts - split in half (two of 6). round 2, split in half (four of 3), round 3 hit else case.
             * continue until we hit the subdiv'th case.
             */
            for (int i = 0; i < subdiv; i++)
            {
                subdivideVerts(ref verts, ref out_tris);
            }
            out_verts = new Unity.Mathematics.float3[verts.Length];

            for (int i = 0; i < verts.Length; i++)
            {
                out_verts[i] = projectPosition(verts[i]);
            }
        }
Exemple #7
0
        public void TestAabb()
        {
            float3 v0 = float3(100, 200, 300);
            float3 v1 = float3(200, 300, 400);
            float3 v2 = float3(50, 100, 350);

            Aabb a0; a0.Min = float3.zero; a0.Max = v0;
            Aabb a1; a1.Min = float3.zero; a1.Max = v1;
            Aabb a2; a2.Min = v2; a2.Max = v1;
            Aabb a3; a3.Min = v2; a3.Max = v0;

            Assert.IsTrue(a0.IsValid);
            Assert.IsTrue(a1.IsValid);
            Assert.IsTrue(a2.IsValid);
            Assert.IsFalse(a3.IsValid);

            Assert.IsTrue(a1.Contains(a0));
            Assert.IsFalse(a0.Contains(a1));
            Assert.IsTrue(a1.Contains(a2));
            Assert.IsFalse(a2.Contains(a1));
            Assert.IsFalse(a0.Contains(a2));
            Assert.IsFalse(a2.Contains(a0));

            // Test Expand / Contains
            {
                Aabb   a5; a5.Min = v2; a5.Max = v1;
                float3 testPoint  = float3(v2.x - 1.0f, v1.y + 1.0f, .5f * (v2.z + v1.z));
                Assert.IsFalse(a5.Contains(testPoint));

                a5.Expand(1.5f);
                Assert.IsTrue(a5.Contains(testPoint));
            }

            // Test transform
            {
                Aabb ut; ut.Min = v0; ut.Max = v1;

                // Identity transform should not modify aabb
                Aabb outAabb = Unity.Physics.Math.TransformAabb(RigidTransform.identity, ut);

                TestUtils.AreEqual(ut.Min, outAabb.Min, 1e-3f);

                // Test translation
                outAabb = Unity.Physics.Math.TransformAabb(new RigidTransform(quaternion.identity, float3(100.0f, 0.0f, 0.0f)), ut);

                Assert.AreEqual(outAabb.Min.x, 200);
                Assert.AreEqual(outAabb.Min.y, 200);
                Assert.AreEqual(outAabb.Max.x, 300);
                Assert.AreEqual(outAabb.Max.z, 400);

                // Test rotation
                quaternion rot = quaternion.EulerXYZ(0.0f, 0.0f, k_pi2);
                outAabb = Unity.Physics.Math.TransformAabb(new RigidTransform(rot, float3.zero), ut);

                TestUtils.AreEqual(outAabb.Min, float3(-300.0f, 100.0f, 300.0f), 1e-3f);
                TestUtils.AreEqual(outAabb.Max, float3(-200.0f, 200.0f, 400.0f), 1e-3f);
                TestUtils.AreEqual(outAabb.SurfaceArea, ut.SurfaceArea, 1e-2f);
            }
        }
Exemple #8
0
        private static float Dot3(Vector3 a, Vector3 b)
        {
#if MATHEMATICS
            return(dot(a, b));
#else
            return(Vector3.Dot(a, b));
#endif
        }
Exemple #9
0
        static float dot(vec3 a, vec3 b)
        {
#if USE_BURST_AND_MATH
            return(math.dot(a, b));
#else
            return(Vector3.Dot(a, b));
#endif
        }
Exemple #10
0
        static vec3 normalize(vec3 a)
        {
#if USE_BURST_AND_MATH
            return(math.normalize(a));
#else
            return(Vector3.Normalize(a));
#endif
        }
Exemple #11
0
        /// <summary>
        /// Checks if the position is below the maximum possible wave height. Can be used as a fast broad-phase check, before actually using the more expensive SampleWaves function
        /// </summary>
        /// <param name="position"></param>
        /// <param name="waterObject"></param>
        /// <returns></returns>
        public static bool CanTouchWater(Vector3 position, WaterObject waterObject)
        {
            if (!waterObject)
            {
                return(false);
            }

            return(position.y < (waterObject.transform.position.y + WaveParameters.GetMaxWaveHeight(waterObject.material)));
        }
Exemple #12
0
        /// <summary>
        /// Returns a position in world-space, where a ray cast from the origin in the direction hits the (flat) water level height
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="direction"></param>
        /// <param name="waterLevel">Water level height in world-space</param>
        /// <returns></returns>
        public static Vector3 FindWaterLevelIntersection(Vector3 origin, Vector3 direction, float waterLevel)
        {
            float upDot = Dot3(direction, UnityEngine.Vector3.up);
            float angle = (Mathf.Acos(upDot) * 180f) / Mathf.PI;

            float depth = waterLevel - origin.y;
            //Distance from origin to water level along direction
            float hypotenuse = depth / Cosine(Mathf.Deg2Rad * angle);

            return(origin + (direction * hypotenuse));
        }
Exemple #13
0
 private void BuildTriangle(Unity.Mathematics.float3x3 vertices, Unity.Mathematics.float3 planePos,
                            Unity.Mathematics.float3 planeNorm)
 {
     UnityEngine.GameObject tri1_go = new UnityEngine.GameObject();
     tri1_go.transform.parent = this.transform;
     tri1_go.AddComponent <TriangleCrossSection>();
     triXC.Add(tri1_go.GetComponent <TriangleCrossSection>());
     tri1_go.GetComponent <TriangleCrossSection>().triangleVerticies = vertices;
     tri1_go.GetComponent <TriangleCrossSection>().planePos          = planePos;
     tri1_go.GetComponent <TriangleCrossSection>().planeNormal       = planeNorm;
     tri1_go.GetComponent <TriangleCrossSection>().mat = mat;
 }
Exemple #14
0
        /// <summary>
        /// Faux-raycast against the water surface
        /// </summary>
        /// <param name="waterMat">Material using StylizedWater2 shader</param>
        /// <param name="waterLevel">Height of the reference water plane.</param>
        /// <param name="origin">Ray origin</param>
        /// <param name="direction">Ray direction</param>
        /// <param name="dynamicMaterial">If true, the material's wave parameters will be re-fetched with every function call</param>
        /// <param name="hit">Reference to a RaycastHit, hit point and normal will be set</param>
        public static void Raycast(Material waterMat, float waterLevel, Vector3 origin, Vector3 direction, bool dynamicMaterial, out RaycastHit hit)
        {
            Vector3 samplePos = FindWaterLevelIntersection(origin, direction, waterLevel);

            float waveHeight = SampleWaves(samplePos, waterMat, waterLevel, 1f, dynamicMaterial, out var normal);

            samplePos.y = waveHeight;

            hit        = Buoyancy.hit;
            hit.normal = normal;
            hit.point  = samplePos;
        }
Exemple #15
0
    private void BuildTetrahedron(Unity.Mathematics.float4[] vertices, Unity.Mathematics.float3 planePos,
                                  Unity.Mathematics.float3 planeNorm)
    {
        UnityEngine.GameObject tet1_go = new UnityEngine.GameObject();
        tet1_go.transform.parent = this.transform;
        tet1_go.AddComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>();
        pyramidXC.Add(tet1_go.GetComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>());

        //TODO project verticies down a dimension.
        //tet1_go.GetComponent<IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>().tetrahderonVertices = vertices;
        tet1_go.GetComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>().planePos    = planePos;
        tet1_go.GetComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>().planeNormal = planeNorm;
        tet1_go.GetComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>().mat         = mat;
    }
Exemple #16
0
        private void BuildCube(Unity.Mathematics.float4[] vertices, Unity.Mathematics.float3 planePos,
                               Unity.Mathematics.float3 planeNorm)
        {
            UnityEngine.GameObject cube1_go = new UnityEngine.GameObject();
            cube1_go.transform.parent = this.transform;
            cube1_go.AddComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>();
            hyperCubeXC.Add(cube1_go.GetComponent <IMRE.ScaleDimension.CrossSections.CubeCrossSection>());

            //TODO project verticies down a dimension.
            //cube1_go.GetComponent<IMRE.ScaleDimension.CrossSections.CubeCrossSecion>().cubeVertices = vertices;
            cube1_go.GetComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>().planePos    = planePos;
            cube1_go.GetComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>().planeNormal = planeNorm;
            cube1_go.GetComponent <IMRE.ScaleDimension.CrossSections.TetrahedronCrossSection>().mat         = mat;
        }
Exemple #17
0
        private static void GetRandomDirections(vec3 halfVoxel, uint seed, ref NativeArray <vec3> samples)
        {
            int count = samples.Length;

#if USE_BURST_AND_MATH
            Random random = new Random(seed);
#endif
            for (int k = 0; k < count; k++)
            {
#if USE_BURST_AND_MATH
                samples[k] = random.NextFloat3Direction() * halfVoxel;
#else
                samples[k] = Vector3.Scale(Random.onUnitSphere, halfVoxel);
#endif
            }
        }
Exemple #18
0
            public void Execute(int index)
            {
                vec3 rd = Samples[index];
                vec3 ro = RayOrigin;

                float nearest = RayLength;

                for (int v = 0; v < 6; v++)
                {
                    if (PlaneRaycast(ro, rd, VolumePlanes[v], out float d))
                    {
                        nearest = min(nearest, d);
                    }
                }

                RayLengths[index] = nearest;
            }
Exemple #19
0
            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);
            }
Exemple #20
0
        private void UpdateTriangles()
        {
            //take vertices and organize them into clockwise triangles to be passed to triangle intersection function
            Unity.Mathematics.float3 a = tetrahderonVertices[0];
            Unity.Mathematics.float3 b = tetrahderonVertices[1];
            Unity.Mathematics.float3 c = tetrahderonVertices[2];
            Unity.Mathematics.float3 d = tetrahderonVertices[3];

            Unity.Mathematics.float3x3 triangle1 = new Unity.Mathematics.float3x3(a, b, c);
            Unity.Mathematics.float3x3 triangle2 = new Unity.Mathematics.float3x3(a, c, d);
            Unity.Mathematics.float3x3 triangle3 = new Unity.Mathematics.float3x3(a, d, b);
            Unity.Mathematics.float3x3 triangle4 = new Unity.Mathematics.float3x3(b, c, d);

            triXC.ForEach(p => p.planePos    = planePos);
            triXC.ForEach(p => p.planeNormal = planeNormal);
            triXC[0].triangleVerticies       = triangle1;
            triXC[1].triangleVerticies       = triangle2;
            triXC[2].triangleVerticies       = triangle3;
            triXC[3].triangleVerticies       = triangle4;
        }
Exemple #21
0
        public unsafe void RigidBodyCastColliderTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;
            const float sphereRadius = 1.0f;

            var rayStartOK = new float3(-10, -10, -10);
            var rayEndOK   = new float3(10, 10, 10);

            var rayStartFail = new float3(-10, 10, -10);
            var rayEndFail   = new float3(10, 10, 10);

            rigidbody.Collider = (Collider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            var colliderCastInput = new ColliderCastInput();
            var closestHit        = new ColliderCastHit();
            var allHits           = new NativeList <ColliderCastHit>(Allocator.Temp);

            // OK case : Sphere hits the box collider
            float3 rayDir = rayEndOK - rayStartOK;

            colliderCastInput.Position  = rayStartOK;
            colliderCastInput.Direction = rayDir;
            colliderCastInput.Collider  = (Collider *)SphereCollider.Create(float3.zero, sphereRadius).GetUnsafePtr();

            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput));
            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput, out closestHit));
            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput, ref allHits));

            // Fail case : wrong direction
            rayDir = rayEndFail - rayStartFail;
            colliderCastInput.Position  = rayStartFail;
            colliderCastInput.Direction = rayDir;

            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput));
            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput, out closestHit));
            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput, ref allHits));
        }
Exemple #22
0
        public void TestAabbTransform()
        {
            Random rnd = new Random(0x12345678);

            for (int i = 0; i < 100; i++)
            {
                quaternion r = rnd.NextQuaternionRotation();
                float3     t = rnd.NextFloat3();

                Aabb orig = new Aabb();
                orig.Include(rnd.NextFloat3());
                orig.Include(rnd.NextFloat3());

                Aabb outAabb1 = Unity.Physics.Math.TransformAabb(new RigidTransform(r, t), orig);

                Physics.Math.MTransform bFromA = new Physics.Math.MTransform(r, t);
                Aabb outAabb2 = Unity.Physics.Math.TransformAabb(bFromA, orig);

                TestUtils.AreEqual(outAabb1.Min, outAabb2.Min, 1e-3f);
                TestUtils.AreEqual(outAabb1.Max, outAabb2.Max, 1e-3f);
            }
        }
Exemple #23
0
        public unsafe void RigidBodyCastRayTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;

            var rayStartOK = new float3(-10, -10, -10);
            var rayEndOK   = new float3(10, 10, 10);

            var rayStartFail = new float3(-10, 10, -10);
            var rayEndFail   = new float3(10, 10, 10);

            rigidbody.Collider = (Collider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            var raycastInput = new RaycastInput();
            var closestHit   = new RaycastHit();
            var allHits      = new NativeList <RaycastHit>(Allocator.Temp);

            // OK case : Ray hits the box collider
            float3 rayDir = rayEndOK - rayStartOK;

            raycastInput.Ray.Origin    = rayStartOK;
            raycastInput.Ray.Direction = rayDir;
            raycastInput.Filter        = CollisionFilter.Default;

            Assert.IsTrue(rigidbody.CastRay(raycastInput));
            Assert.IsTrue(rigidbody.CastRay(raycastInput, out closestHit));
            Assert.IsTrue(rigidbody.CastRay(raycastInput, ref allHits));

            // Fail Case : wrong direction
            rayDir = rayEndFail - rayStartFail;
            raycastInput.Ray.Origin    = rayStartFail;
            raycastInput.Ray.Direction = rayDir;

            Assert.IsFalse(rigidbody.CastRay(raycastInput));
            Assert.IsFalse(rigidbody.CastRay(raycastInput, out closestHit));
            Assert.IsFalse(rigidbody.CastRay(raycastInput, ref allHits));
        }
Exemple #24
0
        public unsafe void RigidBodyCalculateDistanceTest()
        {
            const float size         = 1.0f;
            const float convexRadius = 0.0f;
            const float sphereRadius = 1.0f;

            var queryPos = new float3(-10, -10, -10);

            BlobAssetReference <Collider> boxCollider    = BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius);
            BlobAssetReference <Collider> sphereCollider = SphereCollider.Create(float3.zero, sphereRadius);

            var rigidBody = new Physics.RigidBody
            {
                WorldFromBody = RigidTransform.identity,
                Collider      = (Collider *)boxCollider.GetUnsafePtr()
            };

            var colliderDistanceInput = new ColliderDistanceInput
            {
                Collider  = (Collider *)sphereCollider.GetUnsafePtr(),
                Transform = new RigidTransform(quaternion.identity, queryPos)
            };

            var closestHit = new DistanceHit();
            var allHits    = new NativeList <DistanceHit>(Allocator.Temp);

            // OK case : with enough max distance
            colliderDistanceInput.MaxDistance = 10000.0f;
            Assert.IsTrue(rigidBody.CalculateDistance(colliderDistanceInput));
            Assert.IsTrue(rigidBody.CalculateDistance(colliderDistanceInput, out closestHit));
            Assert.IsTrue(rigidBody.CalculateDistance(colliderDistanceInput, ref allHits));

            // Fail case : not enough max distance
            colliderDistanceInput.MaxDistance = 1;
            Assert.IsFalse(rigidBody.CalculateDistance(colliderDistanceInput));
            Assert.IsFalse(rigidBody.CalculateDistance(colliderDistanceInput, out closestHit));
            Assert.IsFalse(rigidBody.CalculateDistance(colliderDistanceInput, ref allHits));
        }
Exemple #25
0
        public void GenerateControlPoints(Vector3Int newResolution, float3[] resampleOriginalPoints, Vector3Int resampleOriginalResolution)
        {
            resolution = newResolution;

            controlPoints = new float3[resolution.x * resolution.y * resolution.z];
            for (int z = 0; z < resolution.z; z++)
            {
                for (int y = 0; y < resolution.y; y++)
                {
                    for (int x = 0; x < resolution.x; x++)
                    {
                        int index = GetIndex(x, y, z);

                        controlPoints[index] = new float3(x / (float)(newResolution.x - 1) - 0.5f,
                                                          y / (float)(newResolution.y - 1) - 0.5f, z / (float)(newResolution.z - 1) - 0.5f);
                    }
                }
            }

            if (resampleOriginalPoints != null)
            {
                var nativeArray = new NativeArray <float3>(controlPoints, Allocator.TempJob);
                var latticeJob  = new LatticeJob
                {
                    controlPoints = new NativeArray <float3>(resampleOriginalPoints, Allocator.TempJob),
                    resolution    = new int3(resampleOriginalResolution.x, resampleOriginalResolution.y, resampleOriginalResolution.z),
                    meshToTarget  = float4x4.identity,
                    targetToMesh  = float4x4.identity,
                    vertices      = nativeArray
                };
                latticeJob.Run(controlPoints.Length);
                resolution = newResolution;

                nativeArray.CopyTo(controlPoints);
                nativeArray.Dispose();
            }
        }
Exemple #26
0
            public void Execute(int index)
            {
                vec3 rd = Samples[index];
                vec3 ro = RayOrigin;

                Ray ray = new Ray(ro, rd);

                float nearest = RayLength;

                // if(tempBound.IntersectRay(ray, out float d))
                // {
                //     nearest = min(abs(d), nearest);
                // }

                for (int v = 0; v < 6; v++)
                {
                    if (PlaneRaycast(ro, rd, VolumePlanes[v], out float d))
                    {
                        nearest = min(nearest, d);
                    }
                }

                RayLengths[index] = nearest;
            }
        /// <summary>
        ///     Function to render the intersection of a plane and a triangle
        /// </summary>
        /// <param name="height"></param>
        /// <param name="vertices"></param>
        /// <param name="crossSectionRenderer"></param>
        public void crossSectTri(Unity.Mathematics.float3 point, Unity.Mathematics.float3 normalDirection,
                                 Unity.Mathematics.float3[] vertices, UnityEngine.LineRenderer crossSectionRenderer)
        {
            //Vertices are organized in clockwise manner starting from top
            //top vertex
            Unity.Mathematics.float3 a = vertices[0];
            //bottom right
            Unity.Mathematics.float3 b = vertices[1];
            //bottom left
            Unity.Mathematics.float3 c = vertices[2];

            //intermediate calculations
            Unity.Mathematics.float3 ac_hat = (c - a) / UnityEngine.Vector3.Magnitude(c - a);
            Unity.Mathematics.float3 ab_hat = (b - a) / UnityEngine.Vector3.Magnitude(b - a);
            Unity.Mathematics.float3 bc_hat = (c - b) / UnityEngine.Vector3.Magnitude(c - b);

            //points of intersection on each line segment
            Unity.Mathematics.float3 ac_star = IMRE.Math.Operations.SegmentPlaneIntersection(a, c, point, normalDirection);
            Unity.Mathematics.float3 ab_star = IMRE.Math.Operations.SegmentPlaneIntersection(a, b, point, normalDirection);
            Unity.Mathematics.float3 bc_star = IMRE.Math.Operations.SegmentPlaneIntersection(b, c, point, normalDirection);

            //boolean values for if intersection hits only a vertex of the triangle
            bool ac_star_isEndpoint;

            ac_star_isEndpoint = ac_star.Equals(a) || ac_star.Equals(c);
            bool ab_star_isEndpoint;

            ab_star_isEndpoint = ab_star.Equals(a) || ab_star.Equals(b);
            bool bc_star_isEndpoint;

            bc_star_isEndpoint = bc_star.Equals(c) || bc_star.Equals(c);

            //booleans for if intersection hits somewhere on the segments
            bool ac_star_onSegment = !ac_star.Equals(new float3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity));
            bool ab_star_onSegment = !ab_star.Equals(new float3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity));
            bool bc_star_onSegment = !bc_star.Equals(new float3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity));

            //track how many vertices the intersection hits
            int endpointCount = 0;

            if (ac_star_isEndpoint)
            {
                endpointCount++;
            }
            if (ab_star_isEndpoint)
            {
                endpointCount++;
            }
            if (bc_star_isEndpoint)
            {
                endpointCount++;
            }

            //If plane does not hit triangle
            if (!(ab_star_onSegment || ac_star_onSegment || bc_star_onSegment))
            {
                crossSectionRenderer.enabled = false;
                UnityEngine.Debug.Log("Line does not intersect with any of triangle sides.");
            }

            //intersection is a segment (edge) of the triangle
            //the concept for choosing the right points of the cross section is the same for each of these subcases
            //two unique endpoint values
            else if (endpointCount >= 2 &&
                     (!ab_star.Equals(ac_star) || !ab_star.Equals(bc_star) || !ac_star.Equals(bc_star)))
            {
                crossSectionRenderer.enabled = true;
                //if there are two unique values, pick two.
                //drop the result for the edge which is within the plane

                //tolerance accounts for rounding errors
                float tolerance = .00001f;
                if (Unity.Mathematics.math.dot(ab_hat, normalDirection) < tolerance)
                {
                    crossSectionRenderer.SetPosition(0, a);
                    crossSectionRenderer.SetPosition(1, b);
                }
                else if (Unity.Mathematics.math.dot(ac_hat, normalDirection) < tolerance)
                {
                    crossSectionRenderer.SetPosition(0, a);
                    crossSectionRenderer.SetPosition(1, c);
                }
                else if (Unity.Mathematics.math.dot(bc_hat, normalDirection) < tolerance)
                {
                    crossSectionRenderer.SetPosition(0, b);
                    crossSectionRenderer.SetPosition(1, c);
                }
                else
                {
                    Debug.LogWarning("Error in calculation of line plane intersection");
                    crossSectionRenderer.enabled = false;
                }
            }

            //intersection hits one vertex on triangle and one of the segments
            else if (endpointCount == 2 && ab_star.Equals(ac_star) || ab_star.Equals(bc_star) ||
                     ac_star.Equals(bc_star))
            {
                crossSectionRenderer.enabled = true;

                //if point of intersection hits a, it must hit bc_star; same logic applies to remaining subcases
                if (ab_star.Equals(ac_star))
                {
                    crossSectionRenderer.SetPosition(0, a);
                    crossSectionRenderer.SetPosition(1, bc_star);
                }
                else if (ab_star.Equals(bc_star))
                {
                    crossSectionRenderer.SetPosition(0, b);
                    crossSectionRenderer.SetPosition(1, ac_star);
                }
                else if (ac_star.Equals(bc_star))
                {
                    crossSectionRenderer.SetPosition(0, c);
                    crossSectionRenderer.SetPosition(1, ab_star);
                }
                else
                {
                    Debug.LogWarning("Error in calculation of line plane intersection");
                    crossSectionRenderer.enabled = false;
                }
            }
            //intersection hits somewhere on two different segments of triangle; last remaining case
            else
            {
                crossSectionRenderer.enabled = true;

                //find out which two segments are intersected and use their calculated intersections
                if (ac_star_onSegment && ab_star_onSegment)
                {
                    crossSectionRenderer.SetPosition(0, ac_star);
                    crossSectionRenderer.SetPosition(1, ab_star);
                }
                else if (ac_star_onSegment && bc_star_onSegment)
                {
                    crossSectionRenderer.SetPosition(0, ac_star);
                    crossSectionRenderer.SetPosition(1, bc_star);
                }
                else if (ab_star_onSegment && bc_star_onSegment)
                {
                    crossSectionRenderer.SetPosition(0, ab_star);
                    crossSectionRenderer.SetPosition(1, bc_star);
                }
                else
                {
                    Debug.LogWarning("Error in calculation of line plane intersection");
                    crossSectionRenderer.enabled = false;
                }
            }
        }
Exemple #28
0
        public static float3 rotate(quaternion q, float3 v)
        {
            float3 t = 2 * cross(q.value.xyz, v);

            return(v + q.value.w * t + cross(q.value.xyz, t));
        }
Exemple #29
0
        /// <summary>
        /// Returns a quaternion view rotation given a unit length forward vector and a unit length up vector.
        /// The two input vectors are assumed to be unit length and not collinear.
        /// If these assumptions are not met use float3x3.LookRotationSafe instead.
        /// </summary>
        public static quaternion LookRotation(float3 forward, float3 up)
        {
            float3 t = normalize(cross(up, forward));

            return(quaternion(float3x3(t, cross(forward, t), forward)));
        }
Exemple #30
0
 public static float3 mul(float3x3 x, float3 v)
 {
     return(mad(x.c2, v.z, mad(x.c0, v.x, x.c1 * v.y)));
 }