Пример #1
0
        public static void Equal()
        {
            bool result = true;

            for (int i = 0; i < NUM_TESTS; i++)
            {
                bool3 x = TestData_LHS[i] == TestData_RHS[i];

                result &= x.Equals(new bool3(TestData_LHS[i].x == TestData_RHS[i].x,
                                             TestData_LHS[i].y == TestData_RHS[i].y,
                                             TestData_LHS[i].z == TestData_RHS[i].z));
            }

            Assert.AreEqual(true, result);
        }
Пример #2
0
        public static void GreaterThanOrEqual()
        {
            bool result = true;

            for (int i = 0; i < NUM_TESTS; i++)
            {
                bool3 x = TestData_LHS[i] >= TestData_RHS[i];

                result &= x.Equals(new bool3(TestData_LHS[i].x >= TestData_RHS[i].x,
                                             TestData_LHS[i].y >= TestData_RHS[i].y,
                                             TestData_LHS[i].z >= TestData_RHS[i].z));
            }

            Assert.AreEqual(true, result);
        }
Пример #3
0
        private JobHandle BuildRadarLayer(FactionMember factionMember, out CollisionLayer layer, JobHandle inputDeps)
        {
            m_radars.SetSharedComponentFilter(factionMember);
            int count  = m_radars.CalculateEntityCount();
            var bodies = new NativeArray <ColliderBody>(count, Allocator.TempJob);
            var aabbs  = new NativeArray <Aabb>(count, Allocator.TempJob);
            var jh     = Entities.WithAll <AiRadarTag>().WithSharedComponentFilter(factionMember).WithStoreEntityQueryInField(ref m_radars)
                         .ForEach((Entity e, int entityInQueryIndex, in AiShipRadar radar, in LocalToWorld ltw) =>
            {
                var transform = new RigidTransform(quaternion.LookRotationSafe(ltw.Forward, ltw.Up), ltw.Position);
                var sphere    = new SphereCollider(0f, radar.distance);
                if (radar.cosFov < 0f)
                {
                    //Todo: Create tighter bounds here too.
                    aabbs[entityInQueryIndex] = Physics.CalculateAabb(sphere, transform);
                }
                else
                {
                    //Compute aabb of vertex and spherical cap points which are extreme points
                    float3 forward            = math.forward(transform.rot);
                    bool3 positiveOnSphereCap = forward > radar.cosFov;
                    bool3 negativeOnSphereCap = -forward > radar.cosFov;
                    float3 min = math.select(0f, -radar.distance, negativeOnSphereCap);
                    float3 max = math.select(0f, radar.distance, positiveOnSphereCap);
                    Aabb aabb  = new Aabb(min, max);

                    //Compute aabb of circle base
                    float4 cos                = new float4(forward, radar.cosFov);
                    float4 sinSq              = 1f - (cos * cos);
                    float4 sin                = math.sqrt(sinSq);
                    float3 center             = forward * radar.distance * radar.cosFov;
                    float radius              = radar.distance * sin.w;
                    float3 extents            = sin.xyz * radius;
                    min                       = center - extents;
                    max                       = center + extents;
                    aabb.min                  = math.min(aabb.min, min) + transform.pos;
                    aabb.max                  = math.max(aabb.max, max) + transform.pos;
                    aabbs[entityInQueryIndex] = aabb;
                }

                bodies[entityInQueryIndex] = new ColliderBody
                {
                    collider  = sphere,
                    entity    = e,
                    transform = transform
                };
            }).ScheduleParallel(inputDeps);
Пример #4
0
        public static long3 negate(long3 x, bool3 p)
        {
            Assert.IsSafeBoolean(p.x);
            Assert.IsSafeBoolean(p.y);
            Assert.IsSafeBoolean(p.z);

            if (Avx2.IsAvx2Supported)
            {
                long3 mask = (sbyte3)Sse2.cmpgt_epi8(*(v128 *)&p, default(v128));

                return((x ^ mask) - mask);
            }
            else
            {
                return(new long3(negate(x.xy, p.xy), negate(x.z, p.z)));
            }
        }
Пример #5
0
        // BoxBox() helper
        private static bool PointPlanes(MTransform aFromB, float3 halfExtA, float3 halfExtB, float maxDistance, ref float3 normalOut, ref float distanceOut)
        {
            // Calculate the AABB of box B in A-space
            Aabb aabbBinA;
            {
                Aabb aabbBinB = new Aabb {
                    Min = -halfExtB, Max = halfExtB
                };
                aabbBinA = Math.TransformAabb(aFromB, aabbBinB);
            }

            // Check for a miss
            float3 toleranceHalfExt = halfExtA + maxDistance;
            bool3  miss             = (aabbBinA.Min > toleranceHalfExt) | (-toleranceHalfExt > aabbBinA.Max);

            if (math.any(miss))
            {
                return(false);
            }

            // Return the normal with minimum separating distance
            float3 diff0     = aabbBinA.Min - halfExtA;  // positive normal
            float3 diff1     = -aabbBinA.Max - halfExtA; // negative normal
            bool3  greater01 = diff0 > diff1;
            float3 max01     = math.select(diff1, diff0, greater01);

            distanceOut = math.cmax(max01);

            int axis = IndexOfMaxComponent(max01);

            if (axis == 0)
            {
                normalOut = new float3(1.0f, 0.0f, 0.0f);
            }
            else if (axis == 1)
            {
                normalOut = new float3(0.0f, 1.0f, 0.0f);
            }
            else
            {
                normalOut = new float3(0.0f, 0.0f, 1.0f);
            }
            normalOut = math.select(normalOut, -normalOut, greater01);

            return(true);
        }
Пример #6
0
        public static sbyte3 negate(sbyte3 x, bool3 p)
        {
            Assert.IsSafeBoolean(p.x);
            Assert.IsSafeBoolean(p.y);
            Assert.IsSafeBoolean(p.z);

            if (Sse2.IsSse2Supported)
            {
                sbyte3 mask = Sse2.cmpgt_epi8(*(v128 *)&p, default(v128));

                return((x ^ mask) - mask);
            }
            else
            {
                sbyte3 mask = toint8(p);

                return((x ^ -mask) + mask);
            }
        }
Пример #7
0
        void ConvertCharacterJoint(LegacyCharacter joint)
        {
            var linearLocks   = new bool3(true);
            var linearLimited = new bool3(false);

            var angularFree    = new bool3(false);
            var angularLocks   = new bool3(false);
            var angularLimited = new bool3(true);

            var jointFrameOrientation = GetJointFrameOrientation(joint.axis, joint.swingAxis);
            var jointData             = CreateConfigurableJoint(jointFrameOrientation, joint, linearLocks, linearLimited, new SoftJointLimit {
                limit = 0f, bounciness = 0f
            }, new SoftJointLimitSpring {
                spring = 0f, damper = 0f
            }, angularFree, angularLocks, angularLimited,
                                                                joint.lowTwistLimit, joint.highTwistLimit, joint.twistLimitSpring, joint.swing1Limit, joint.swing2Limit, joint.swingLimitSpring);

            m_EndJointConversionSystem.CreateJointEntity(joint, GetConstrainedBodyPair(joint), jointData);
        }
        void ConvertConfigurableJoint(LegacyConfigurable joint)
        {
            var linearLocks = new bool3
                              (
                IsMotionLocked(joint.xMotion),
                IsMotionLocked(joint.yMotion),
                IsMotionLocked(joint.zMotion)
                              );

            var linearLimited = new bool3
                                (
                IsMotionLimited(joint.xMotion),
                IsMotionLimited(joint.yMotion),
                IsMotionLimited(joint.zMotion)
                                );

            var angularFree = new bool3
                              (
                IsMotionFree(joint.angularXMotion),
                IsMotionFree(joint.angularYMotion),
                IsMotionFree(joint.angularZMotion)
                              );

            var angularLocks = new bool3
                               (
                IsMotionLocked(joint.angularXMotion),
                IsMotionLocked(joint.angularYMotion),
                IsMotionLocked(joint.angularZMotion)
                               );

            var angularLimited = new bool3
                                 (
                IsMotionLimited(joint.angularXMotion),
                IsMotionLimited(joint.angularYMotion),
                IsMotionLimited(joint.angularZMotion)
                                 );

            var jointFrameOrientation = GetJointFrameOrientation(joint.axis, joint.secondaryAxis);
            var jointData             = CreateConfigurableJoint(jointFrameOrientation, joint, linearLocks, linearLimited, joint.linearLimit, joint.linearLimitSpring, angularFree, angularLocks, angularLimited,
                                                                joint.lowAngularXLimit, joint.highAngularXLimit, joint.angularXLimitSpring, joint.angularYLimit, joint.angularZLimit, joint.angularYZLimitSpring);

            CreateJointEntity(joint.gameObject, jointData, GetPrimaryEntity(joint.gameObject), joint.connectedBody == null ? Entity.Null : GetPrimaryEntity(joint.connectedBody), joint.enableCollision);
        }
Пример #9
0
        public static void Bool3()
        {
            Random32 rng = new Random32(RNG_SEED);

            bool result = true;

            for (int i = 0; i < NUM_TESTS; i++)
            {
                int   r = rng.NextInt();
                bool3 x = maxmath.tobool3(r);

                for (int j = 0; j < 3; j++)
                {
                    result &= x[j] == System.Convert.ToBoolean((r >> j) & 1);
                }
            }

            Assert.AreEqual(true, result);
        }
        void ConvertCharacterJoint(LegacyCharacter joint)
        {
            var linearLocks   = new bool3(true);
            var linearLimited = new bool3(false);

            var angularFree    = new bool3(false);
            var angularLocks   = new bool3(false);
            var angularLimited = new bool3(true);

            var jointFrameOrientation = GetJointFrameOrientation(joint.axis, joint.swingAxis);
            var jointData             = CreateConfigurableJoint(jointFrameOrientation, joint, linearLocks, linearLimited, new SoftJointLimit {
                limit = 0f, bounciness = 0f
            }, new SoftJointLimitSpring {
                spring = 0f, damper = 0f
            }, angularFree, angularLocks, angularLimited,
                                                                joint.lowTwistLimit, joint.highTwistLimit, joint.twistLimitSpring, joint.swing1Limit, joint.swing2Limit, joint.swingLimitSpring);

            CreateJointEntity(joint.gameObject, jointData, GetPrimaryEntity(joint.gameObject), joint.connectedBody == null ? Entity.Null : GetPrimaryEntity(joint.connectedBody), joint.enableCollision);
        }
Пример #11
0
            bool BoxIntersectDecal(float3x4 localToWorld, float4 *planes, float3 decalMin, float3 decalMax)
            {
                float3 position         = localToWorld.c3;
                bool3  minLargerThanMax = camMinPos > decalMax;
                bool3  maxLessThanMin   = camMaxPos < decalMin;

                minLargerThanMax |= maxLessThanMin;
                if (minLargerThanMax.x || minLargerThanMax.y || minLargerThanMax.z || maxLessThanMin.x || maxLessThanMin.y || maxLessThanMin.z)
                {
                    return(false);
                }
                for (uint i = 0; i < 6; ++i)
                {
                    float4 plane     = planes[i];
                    float3 absNormal = abs(mul(plane.xyz, float3x3(localToWorld.c0, localToWorld.c1, localToWorld.c2)));
                    if ((dot(position, plane.xyz) - dot(absNormal, 0.5f)) > -plane.w)
                    {
                        return(false);
                    }
                }
                return(true);
            }
        public static void fp3_operator_not_equal_wide_scalar()
        {
            fp3 a0 = fp3(-155.4411m, -19.4266052m, 174.633057m);
            fp b0 = (-393.413544m);
            bool3 r0 = bool3(true, true, true);
            TestUtils.AreEqual(a0 != b0, r0);

            fp3 a1 = fp3(507.920715m, 171.151489m, -58.92328m);
            fp b1 = (59.177063m);
            bool3 r1 = bool3(true, true, true);
            TestUtils.AreEqual(a1 != b1, r1);

            fp3 a2 = fp3(-398.176849m, -165.241516m, 270.341m);
            fp b2 = (492.20105m);
            bool3 r2 = bool3(true, true, true);
            TestUtils.AreEqual(a2 != b2, r2);

            fp3 a3 = fp3(-380.243256m, -134.345459m, 458.400452m);
            fp b3 = (501.899048m);
            bool3 r3 = bool3(true, true, true);
            TestUtils.AreEqual(a3 != b3, r3);
        }
        // ray direction is assumed to be normalized
        public static bool Hit(this Box box, Ray r, float tMin, float tMax, out float distance, out float3 normal)
        {
            // offset origin by tMin
            r = new Ray(r.Origin + r.Direction * tMin, r.Direction, r.Time);

            distance = 0;
            normal   = 0;

            // from "A Ray-Box Intersection Algorithm and Efficient Dynamic Voxel Rendering" (Majercik et al.)
            // http://jcgt.org/published/0007/03/04/
            float3 rayDirection    = r.Direction;
            float  winding         = cmax(abs(r.Origin) * box.InverseExtents) < 1 ? -1 : 1;
            float3 sgn             = -sign(rayDirection);
            float3 distanceToPlane = (box.Extents * winding * sgn - r.Origin) / rayDirection;

            bool3 test = distanceToPlane >= 0 & bool3(
                all(abs(r.Origin.yz + rayDirection.yz * distanceToPlane.x) < box.Extents.yz),
                all(abs(r.Origin.zx + rayDirection.zx * distanceToPlane.y) < box.Extents.zx),
                all(abs(r.Origin.xy + rayDirection.xy * distanceToPlane.z) < box.Extents.xy));

            sgn = test.x ? float3(sgn.x, 0, 0) : test.y ? float3(0, sgn.y, 0) : float3(0, 0, test.z ? sgn.z : 0);
            bool3 nonZero = sgn != 0;

            if (!any(nonZero))
            {
                return(false);
            }

            distance  = nonZero.x ? distanceToPlane.x : nonZero.y ? distanceToPlane.y : distanceToPlane.z;
            distance += tMin;

            if (distance > tMax)
            {
                return(false);
            }

            normal = sgn;
            return(true);
        }
        public void bool3_operator_logical_not()
        {
            bool3 a0 = bool3(true, true, false);
            bool3 r0 = bool3(false, false, true);

            TestUtils.AreEqual(!a0, r0);

            bool3 a1 = bool3(false, false, true);
            bool3 r1 = bool3(true, true, false);

            TestUtils.AreEqual(!a1, r1);

            bool3 a2 = bool3(false, false, false);
            bool3 r2 = bool3(true, true, true);

            TestUtils.AreEqual(!a2, r2);

            bool3 a3 = bool3(false, true, true);
            bool3 r3 = bool3(true, false, false);

            TestUtils.AreEqual(!a3, r3);
        }
Пример #15
0
        public void ConversionSystems_WhenGOHasConfigurableJoint_AngularMotionLockOrLimited_AxesAreConstrained(
            ConfigurableJointMotion angularXMotion, ConfigurableJointMotion angularYMotion, ConfigurableJointMotion angularZMotion,
            bool expectedConstrainedX, bool expectedConstrainedY, bool expectedConstrainedZ
            )
        {
            CreateHierarchy(new[] { typeof(LegacyConfigurable) }, Array.Empty <Type>(), Array.Empty <Type>());
            var joint = Root.GetComponent <LegacyConfigurable>();

            joint.xMotion        = ConfigurableJointMotion.Free;
            joint.yMotion        = ConfigurableJointMotion.Free;
            joint.zMotion        = ConfigurableJointMotion.Free;
            joint.angularXMotion = angularXMotion;
            joint.angularYMotion = angularYMotion;
            joint.angularZMotion = angularZMotion;

            TestConvertedData <PhysicsJoint>(j =>
            {
                Assume.That(j.GetConstraints().Length, Is.EqualTo(1), "ConfigurableJoint with limits on only one axis should produce exactly 1 constraint");
                var expectedConstrainedAxes = new bool3(expectedConstrainedX, expectedConstrainedY, expectedConstrainedZ);
                Assert.That(j[0].ConstrainedAxes, Is.EqualTo(expectedConstrainedAxes));
            });
        }
        public static void fp3_operator_equal_scalar_wide()
        {
            fp a0 = (36.38391m);
            fp3 b0 = fp3(-400.4892m, -71.2868347m, 156.978088m);
            bool3 r0 = bool3(false, false, false);
            TestUtils.AreEqual(a0 == b0, r0);

            fp a1 = (-225.238739m);
            fp3 b1 = fp3(499.141785m, -211.979919m, 428.311951m);
            bool3 r1 = bool3(false, false, false);
            TestUtils.AreEqual(a1 == b1, r1);

            fp a2 = (-489.501343m);
            fp3 b2 = fp3(-5.691559m, -30.8659363m, -362.9831m);
            bool3 r2 = bool3(false, false, false);
            TestUtils.AreEqual(a2 == b2, r2);

            fp a3 = (184.503174m);
            fp3 b3 = fp3(-160.470612m, 316.668823m, 390.369263m);
            bool3 r3 = bool3(false, false, false);
            TestUtils.AreEqual(a3 == b3, r3);
        }
        public static void fp3_operator_equal_wide_scalar()
        {
            fp3 a0 = fp3(65.6712m, 404.415527m, -269.730164m);
            fp b0 = (-155.815765m);
            bool3 r0 = bool3(false, false, false);
            TestUtils.AreEqual(a0 == b0, r0);

            fp3 a1 = fp3(83.6306152m, -155.868286m, 314.671265m);
            fp b1 = (152.9945m);
            bool3 r1 = bool3(false, false, false);
            TestUtils.AreEqual(a1 == b1, r1);

            fp3 a2 = fp3(386.365173m, -132.6352m, -65.66748m);
            fp b2 = (290.04895m);
            bool3 r2 = bool3(false, false, false);
            TestUtils.AreEqual(a2 == b2, r2);

            fp3 a3 = fp3(-69.68326m, 186.845215m, -232.895691m);
            fp b3 = (-191.190765m);
            bool3 r3 = bool3(false, false, false);
            TestUtils.AreEqual(a3 == b3, r3);
        }
        public static void fp3_operator_equal_wide_wide()
        {
            fp3 a0 = fp3(-135.18924m, -49.0941162m, 169.129822m);
            fp3 b0 = fp3(-220.014648m, 66.98004m, 499.2016m);
            bool3 r0 = bool3(false, false, false);
            TestUtils.AreEqual(a0 == b0, r0);

            fp3 a1 = fp3(240.8053m, 314.7392m, 442.393m);
            fp3 b1 = fp3(-371.1131m, 208.448669m, 390.8037m);
            bool3 r1 = bool3(false, false, false);
            TestUtils.AreEqual(a1 == b1, r1);

            fp3 a2 = fp3(177.924438m, 335.5334m, 168.15448m);
            fp3 b2 = fp3(-72.44382m, 362.97644m, 194.678345m);
            bool3 r2 = bool3(false, false, false);
            TestUtils.AreEqual(a2 == b2, r2);

            fp3 a3 = fp3(350.729553m, 367.178467m, 46.9414673m);
            fp3 b3 = fp3(471.644836m, -404.044678m, -144.696747m);
            bool3 r3 = bool3(false, false, false);
            TestUtils.AreEqual(a3 == b3, r3);
        }
        public static void fp3_operator_not_equal_scalar_wide()
        {
            fp a0 = (478.353149m);
            fp3 b0 = fp3(459.553223m, 436.453247m, -488.714172m);
            bool3 r0 = bool3(true, true, true);
            TestUtils.AreEqual(a0 != b0, r0);

            fp a1 = (392.767944m);
            fp3 b1 = fp3(-266.736633m, 338.557861m, -338.100128m);
            bool3 r1 = bool3(true, true, true);
            TestUtils.AreEqual(a1 != b1, r1);

            fp a2 = (-152.314545m);
            fp3 b2 = fp3(-452.820679m, 209.439331m, 50.10797m);
            bool3 r2 = bool3(true, true, true);
            TestUtils.AreEqual(a2 != b2, r2);

            fp a3 = (372.4344m);
            fp3 b3 = fp3(-488.0213m, 489.740784m, 270.4001m);
            bool3 r3 = bool3(true, true, true);
            TestUtils.AreEqual(a3 != b3, r3);
        }
Пример #20
0
        public static void bool3_operator_logical_not()
        {
            bool3 a0 = bool3(true, true, false);
            bool3 r0 = bool3(false, false, true);

            TestUtils.AreEqual(r0, !a0);

            bool3 a1 = bool3(false, false, true);
            bool3 r1 = bool3(true, true, false);

            TestUtils.AreEqual(r1, !a1);

            bool3 a2 = bool3(false, false, false);
            bool3 r2 = bool3(true, true, true);

            TestUtils.AreEqual(r2, !a2);

            bool3 a3 = bool3(false, true, true);
            bool3 r3 = bool3(true, false, false);

            TestUtils.AreEqual(r3, !a3);
        }
        public static void fp3_operator_not_equal_wide_wide()
        {
            fp3 a0 = fp3(279.994141m, -43.34201m, -465.724731m);
            fp3 b0 = fp3(-460.9121m, -476.009033m, 468.1364m);
            bool3 r0 = bool3(true, true, true);
            TestUtils.AreEqual(a0 != b0, r0);

            fp3 a1 = fp3(317.466553m, 85.7149658m, 360.8905m);
            fp3 b1 = fp3(-341.012543m, -62.65805m, -458.801666m);
            bool3 r1 = bool3(true, true, true);
            TestUtils.AreEqual(a1 != b1, r1);

            fp3 a2 = fp3(366.081543m, 154.542847m, 332.4262m);
            fp3 b2 = fp3(-457.730225m, -59.5232544m, 3.024231m);
            bool3 r2 = bool3(true, true, true);
            TestUtils.AreEqual(a2 != b2, r2);

            fp3 a3 = fp3(397.11322m, -431.374969m, 489.0108m);
            fp3 b3 = fp3(155.812744m, -19.8399048m, -6.01693726m);
            bool3 r3 = bool3(true, true, true);
            TestUtils.AreEqual(a3 != b3, r3);
        }
Пример #22
0
        private bool3 OffsetExceedsBounds(float3 offset, float3 minOffset, float3 maxOffset, out bool3 positiveDirection, out float3 newOffset)
        {
            bool3 exceeds = false;

            newOffset         = maxOffset - 0.01f;
            positiveDirection = true;
            if (offset.x > maxOffset.x)
            {
                exceeds.x = true;
            }
            else if (offset.x < minOffset.x)
            {
                exceeds.x           = true;
                positiveDirection.x = false;
                newOffset.x         = minOffset.x + 0.01f;
            }
            if (offset.y > maxOffset.y)
            {
                exceeds.y = true;
            }
            else if (offset.y < minOffset.y)
            {
                exceeds.y           = true;
                positiveDirection.y = false;
                newOffset.y         = minOffset.y + 0.01f;
            }
            if (offset.z > maxOffset.z)
            {
                exceeds.z = true;
            }
            else if (offset.z < minOffset.z)
            {
                exceeds.z           = true;
                positiveDirection.z = false;
                newOffset.z         = minOffset.z + 0.01f;
            }
            return(exceeds);
        }
        public static PhysicsJoint CreateLimitDOFJoint(RigidTransform offset, bool3 linearLocks, bool3 angularLocks)
        {
            var constraints = new FixedList128 <Constraint>();

            if (math.any(linearLocks))
            {
                constraints.Add(new Constraint
                {
                    ConstrainedAxes = linearLocks,
                    Type            = ConstraintType.Linear,
                    Min             = 0,
                    Max             = 0,
                    SpringFrequency = Constraint.DefaultSpringFrequency,
                    SpringDamping   = Constraint.DefaultSpringDamping
                });
            }
            if (math.any(angularLocks))
            {
                constraints.Add(new Constraint
                {
                    ConstrainedAxes = angularLocks,
                    Type            = ConstraintType.Angular,
                    Min             = 0,
                    Max             = 0,
                    SpringFrequency = Constraint.DefaultSpringFrequency,
                    SpringDamping   = Constraint.DefaultSpringDamping
                });
            }

            var joint = new PhysicsJoint
            {
                BodyAFromJoint = BodyFrame.Identity,
                BodyBFromJoint = offset
            };

            joint.SetConstraints(constraints);
            return(joint);
        }
Пример #24
0
        public static BlobAssetReference <JointData> CreateLimitDOFJoint(
            RigidTransform offset, bool3 linearLocks, bool3 angularLocks)
        {
            var constraintCount = (math.any(linearLocks) ? 1 : 0) + (math.any(angularLocks) ? 1 : 0);

            Constraint[] constraints = new Constraint[constraintCount];
            int          index       = 0;

            if (math.any(linearLocks))
            {
                constraints[index++] = new Constraint
                {
                    ConstrainedAxes = linearLocks,
                    Type            = ConstraintType.Linear,
                    Min             = 0,
                    Max             = 0,
                    SpringFrequency = Constraint.DefaultSpringFrequency,
                    SpringDamping   = Constraint.DefaultSpringDamping
                };
            }
            if (math.any(angularLocks))
            {
                constraints[index++] = new Constraint
                {
                    ConstrainedAxes = angularLocks,
                    Type            = ConstraintType.Angular,
                    Min             = 0,
                    Max             = 0,
                    SpringFrequency = Constraint.DefaultSpringFrequency,
                    SpringDamping   = Constraint.DefaultSpringDamping
                };
            }
            return(JointData.Create(
                       new Math.MTransform(float3x3.identity, float3.zero),
                       new Math.MTransform(offset),
                       constraints
                       ));
        }
Пример #25
0
            //[WriteOnly] public NativeArray<float3> accRegistry;


            public void Execute(ref StarEntity currentStar)
            {
                //int starRef=0;
                float3 accForce = float3(0, 0, 0);

                for (int i = 0; i < stars.Length; i++)
                {
                    //the attraction direction
                    float3 distVect     = stars[i].position.Value - currentStar.position.Value;
                    bool3  samePosition = currentStar.position.Value != stars[i].position.Value;
                    //If distance is (0,0,0), we have currentStar being stars[i], so we don't compute
                    if (samePosition.x || samePosition.y || samePosition.z)
                    {
                        float3 distNorm   = normalize(distVect);
                        float  attraction = (6.67f * currentStar.mass.Value * stars[i].mass.Value) / (pow(distVect.x, 2) + pow(distVect.y, 2) + pow(distVect.z, 2)) / 10000;
                        accForce += attraction * distNorm;
                    }
                    // else
                    //starRef = i;
                }
                //accRegistry[starRef] = accForce;
                currentStar.acceleration.Value = accForce;
            }
Пример #26
0
        public static void Bool3()
        {
            bool result = true;

            Random32 rng = new Random32(RNG_SEED);

            for (int i = 0; i < NUM_TESTS; i++)
            {
                bool3 x = rng.NextBool3();

                int test = maxmath.first(x);

                int j = 0;
                while (j < 3 && !x[j])
                {
                    j++;
                }

                result &= test == j;
            }

            Assert.AreEqual(result && maxmath.first(default(bool3)) == 4, true);
        }
Пример #27
0
            public static bool IsObjectIsInFrontOf(IsometricData isoObjectLeft, IsometricData isoObjectRight)
            {
                var leftMinCal  = new float3(-isoObjectLeft.IsoPosition.x, isoObjectLeft.IsoPosition.y, isoObjectRight.IsoPosition.z);
                var leftMaxCal  = leftMinCal + new float3(isoObjectLeft.IsoSize.xy, isoObjectRight.IsoSize.z);
                var rightMinCal = new float3(-isoObjectRight.IsoPosition.x, isoObjectRight.IsoPosition.y, isoObjectLeft.IsoPosition.z);
                var rightMaxCal = rightMinCal + new float3(isoObjectRight.IsoSize.xy, isoObjectLeft.IsoSize.z);

                //from https://shaunlebron.github.io/IsometricBlocks/
                bool leftCanBeInFront = math.all(leftMaxCal > rightMinCal);

                if (leftCanBeInFront)
                {
                    //from http://bannalia.blogspot.com/2008/02/filmation-math.html
                    bool rightCanBeInFront = math.all(rightMaxCal > leftMinCal);

                    if (rightCanBeInFront)
                    {
                        //left and right can be in front, search deeper
                        var deltaLeftToRight = leftMaxCal - rightMinCal;
                        var deltaRightToLeft = rightMaxCal - leftMinCal;

                        var deltaProjection = isoObjectLeft.IsoSize + isoObjectRight.IsoSize - math.abs(deltaRightToLeft - deltaLeftToRight);

                        var condition = new bool2(deltaProjection.y <= deltaProjection.x && deltaProjection.y <= deltaProjection.z,
                                                  deltaProjection.x <= deltaProjection.y && deltaProjection.x <= deltaProjection.z);

                        //better than an if else if for vectorization
                        var res = new bool3(condition.x & (deltaLeftToRight.y > deltaRightToLeft.y),
                                            (condition.x == false) & condition.y & (deltaLeftToRight.x > deltaRightToLeft.x),
                                            (math.any(condition.xy) == false) & (deltaLeftToRight.z > deltaRightToLeft.z));

                        return(math.any(res));
                    }
                }

                return(leftCanBeInFront);
            }
Пример #28
0
        public void StringInterop()
        {
            var v = new bool3(true, false, false);

            var s0 = v.ToString();
            var s1 = v.ToString("#");

            var v0 = bool3.Parse(s0);
            var v1 = bool3.Parse(s1, "#");

            Assert.AreEqual(v, v0);
            Assert.AreEqual(v, v1);

            var b0 = bool3.TryParse(s0, out v0);
            var b1 = bool3.TryParse(s1, "#", out v1);

            Assert.That(b0);
            Assert.That(b1);
            Assert.AreEqual(v, v0);
            Assert.AreEqual(v, v1);

            b0 = bool3.TryParse(null, out v0);
            Assert.False(b0);
            b0 = bool3.TryParse("", out v0);
            Assert.False(b0);
            b0 = bool3.TryParse(s0 + ", 0", out v0);
            Assert.False(b0);

            Assert.Throws <NullReferenceException>(() => { bool3.Parse(null); });
            Assert.Throws <FormatException>(() => { bool3.Parse(""); });
            Assert.Throws <FormatException>(() => { bool3.Parse(s0 + ", 0"); });

            var s2 = v.ToString(";", CultureInfo.InvariantCulture);

            Assert.That(s2.Length > 0);
        }
Пример #29
0
        public void Indexer()
        {
            var v = new bool3(true, false, true);

            Assert.AreEqual(true, v[0]);
            Assert.AreEqual(false, v[1]);
            Assert.AreEqual(true, v[2]);

            Assert.Throws <ArgumentOutOfRangeException>(() => { var s = v[-2147483648]; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { v[-2147483648] = false; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { var s = v[-1]; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { v[-1] = false; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { var s = v[3]; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { v[3] = false; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { var s = v[2147483647]; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { v[2147483647] = false; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { var s = v[5]; });
            Assert.Throws <ArgumentOutOfRangeException>(() => { v[5] = false; });

            v[2] = false;
            Assert.AreEqual(false, v[2]);
            v[0] = true;
            Assert.AreEqual(true, v[0]);
        }
Пример #30
0
        //All algorithms return a negative distance if inside the collider.

        /*public static bool DistanceBetween(float3 point, SphereCollider sphere, float maxDistance, out PointDistanceResultInternal result)
         * {
         *  float3 delta = sphere.center - point;
         *  float pcDistanceSq = math.lengthsq(delta);  //point center distance
         *  bool distanceIsZero = pcDistanceSq == 0.0f;
         *  float invPCDistance = math.select(math.rsqrt(pcDistanceSq), 0.0f, distanceIsZero);
         *  float3 inNormal = math.select(delta * invPCDistance, new float3(0, 1, 0), distanceIsZero);  // choose an arbitrary normal when the distance is zero
         *  float distance = pcDistanceSq * invPCDistance - sphere.radius;
         *  result = new PointDistanceResultInternal
         *  {
         *      hitpoint = point + inNormal * distance,
         *      distance = distance,
         *      normal = -inNormal,
         *  };
         *  return distance <= maxDistance;
         * }*/

        /*public static bool DistanceBetween(float3 point, CapsuleCollider capsule, float maxDistance, out PointDistanceResultInternal result)
         * {
         *  //Strategy: Project p onto the capsule's line clamped to the segment. Then inflate point on line as sphere
         *  float3 edge = capsule.pointB - capsule.pointA;
         *  float3 ap = point - capsule.pointA;
         *  float dot = math.dot(ap, edge);
         *  float edgeLengthSq = math.lengthsq(edge);
         *  dot = math.clamp(dot, 0f, edgeLengthSq);
         *  float3 pointOnSegment = capsule.pointA + edge * dot / edgeLengthSq;
         *  SphereCollider sphere = new SphereCollider(pointOnSegment, capsule.radius);
         *  return DistanceBetween(point, sphere, maxDistance, out result);
         * }*/

        /*public static bool DistanceBetween(float3 point, CylinderCollider cylinder, float maxDistance, out PointDistanceResultInternal result)
         * {
         *  //Strategy: Project p onto the capsule's line.
         *  //If on the segment, do point vs sphere.
         *  //Otherwise do point vs disk
         *  float3 edge = cylinder.pointB - cylinder.pointA;
         *  float3 ap = point - cylinder.pointA;
         *  float3 unitEdge = math.normalize(edge);
         *  float dot = math.dot(ap, unitEdge);  //dot is distance of projected point from pointA
         *  float3 pointOnLine = cylinder.pointA + unitEdge * dot;
         *  if (dot < 0f)
         *  {
         *      //Todo: Optimize math
         *      float3 pointOnLineToPoint = point - pointOnLine;  //This gives us our direction from the center of the cap to the edge towards the query point.
         *      if (math.lengthsq(pointOnLineToPoint) > cylinder.radius * cylinder.radius)
         *      {
         *          float3 roundNormal = math.normalize(pointOnLineToPoint);
         *          float3 capNormal = -unitEdge;
         *          result.normal = (roundNormal + capNormal) / math.SQRT2;  //Summing orthogonal unit vectors has a length of sqrt2
         *          result.hitpoint = cylinder.pointA + roundNormal * cylinder.radius;
         *          result.distance = math.distance(point, result.hitpoint);
         *      }
         *      else
         *      {
         *          result.normal = -unitEdge;
         *          result.distance = -dot;
         *          result.hitpoint = point + unitEdge * result.distance;
         *      }
         *      return result.distance <= maxDistance;
         *  }
         *  if (dot * dot > math.lengthsq(edge))
         *  {
         *      //Todo: Optimize math
         *      float3 pointOnLineToPoint = point - pointOnLine;  //This gives us our direction from the center of the cap to the edge towards the query point.
         *      if (math.lengthsq(pointOnLineToPoint) > cylinder.radius * cylinder.radius)
         *      {
         *          float3 roundNormal = math.normalize(pointOnLineToPoint);
         *          float3 capNormal = unitEdge;
         *          result.normal = (roundNormal + capNormal) / math.SQRT2;  //Summing orthogonal unit vectors has a length of sqrt2
         *          result.hitpoint = cylinder.pointB + roundNormal * cylinder.radius;
         *          result.distance = math.distance(point, result.hitpoint);
         *      }
         *      else
         *      {
         *          result.normal = unitEdge;
         *          result.distance = math.distance(pointOnLine, cylinder.pointB);
         *          result.hitpoint = point - unitEdge * result.distance;
         *      }
         *      return result.distance <= maxDistance;
         *  }
         *  else
         *  {
         *      SphereCollider sphere = new SphereCollider(pointOnLine, cylinder.radius);
         *      return DistanceBetween(point, sphere, maxDistance, out result);
         *  }
         * }*/

        public static bool DistanceBetween(float3 point, BoxCollider box, float maxDistance, out PointDistanceResultInternal result)
        {
            //Idea: The positive octant of the box contains 7 feature regions: 3 faces, 3 edges, and inside.
            //The other octants are identical except with flipped signs. So if we unflip signs,
            //calculate the distance for these 7 regions, and then flip signs again, we get a valid result.
            //We use feature regions rather than feature types to avoid swizzling since that would require a second branch.
            float3 osPoint    = point - box.center;                         //os = origin space
            bool3  isNegative = osPoint < 0f;
            float3 ospPoint   = math.select(osPoint, -osPoint, isNegative); //osp = origin space positive
            int    region     = math.csum(math.select(new int3(4, 2, 1), int3.zero, ospPoint < box.halfSize));

            switch (region)
            {
            case 0:
            {
                //Inside the box. Get the closest wall.
                float3 delta   = box.halfSize - ospPoint;
                float  min     = math.cmin(delta);
                bool3  minMask = min == delta;
                //Prioritize y first, then z, then x if multiple distances perfectly match.
                //Todo: Should this be configurabe?
                minMask.xz     &= !minMask.y;
                minMask.x      &= !minMask.z;
                result.hitpoint = math.select(ospPoint, box.halfSize, minMask);
                result.distance = -min;
                result.normal   = math.select(0f, 1f, minMask);
                break;
            }

            case 1:
            {
                //xy in box, z outside
                //Closest feature is the z-face
                result.distance = ospPoint.z - box.halfSize.z;
                result.hitpoint = new float3(ospPoint.xy, box.halfSize.z);
                result.normal   = new float3(0f, 0f, 1f);
                break;
            }

            case 2:
            {
                //xz in box, y outside
                //Closest feature is the y-face
                result.distance = ospPoint.y - box.halfSize.y;
                result.hitpoint = new float3(ospPoint.x, box.halfSize.y, ospPoint.z);
                result.normal   = new float3(0f, 1f, 0f);
                break;
            }

            case 3:
            {
                //x in box, yz outside
                //Closest feature is the x-axis edge
                result.distance = math.distance(ospPoint.yz, box.halfSize.yz);
                result.hitpoint = new float3(ospPoint.x, box.halfSize.yz);
                result.normal   = new float3(0f, math.SQRT2 / 2f, math.SQRT2 / 2f);
                break;
            }

            case 4:
            {
                //yz in box, x outside
                //Closest feature is the x-face
                result.distance = ospPoint.x - box.halfSize.x;
                result.hitpoint = new float3(box.halfSize.x, ospPoint.yz);
                result.normal   = new float3(1f, 0f, 0f);
                break;
            }

            case 5:
            {
                //y in box, xz outside
                //Closest feature is the y-axis edge
                result.distance = math.distance(ospPoint.xz, box.halfSize.xz);
                result.hitpoint = new float3(box.halfSize.x, ospPoint.y, box.halfSize.y);
                result.normal   = new float3(math.SQRT2 / 2f, 0f, math.SQRT2 / 2f);
                break;
            }

            case 6:
            {
                //z in box, xy outside
                //Closest feature is the z-axis edge
                result.distance = math.distance(ospPoint.xy, box.halfSize.xy);
                result.hitpoint = new float3(box.halfSize.xy, ospPoint.z);
                result.normal   = new float3(math.SQRT2 / 2f, math.SQRT2 / 2f, 0f);
                break;
            }

            default:
            {
                //xyz outside box
                ////Closest feature is the osp corner
                result.distance = math.distance(ospPoint, box.halfSize);
                result.hitpoint = box.halfSize;
                result.normal   = math.normalize(math.float3(1f));
                break;
            }
            }
            result.hitpoint = math.select(result.hitpoint, -result.hitpoint, isNegative) + box.center;
            result.normal   = math.select(result.normal, -result.normal, isNegative);
            return(result.distance <= maxDistance);
        }