Ejemplo n.º 1
0
    // for human agents
    bool ApplyDamage(AgentHuman inAgent, Vector3 inExplosionPos, float inDmgMultiplier)
    {
        Vector3 tmp  = ClosestPoint.PointBounds(inExplosionPos, inAgent.CharacterController.bounds);
        float   dist = (inExplosionPos - tmp).sqrMagnitude;

        if (dist > damageRadius * damageRadius)
        {
            return(false);
        }

#if DEBUG
        DebugDraw.Diamond(Color.grey, 0.02f, tmp);
        DebugDraw.LineOriented(Color.grey, inExplosionPos, tmp, 0.04f);
#endif

        int idx = inAgent.ExplosionHitTargets != null ? inAgent.ExplosionHitTargets.Length : 0;

        while (idx-- > 0)
        {
            if (CheckHit(inAgent.ExplosionHitTargets[idx], inExplosionPos, ref tmp))
            {
                float coef = 1.0f - Mathf.Clamp01(Mathf.Sqrt(dist) / damageRadius);

                Damage  = BaseDamage * coef * inDmgMultiplier;
                Impulse = tmp;

                inAgent.SendMessage("OnExplosionHit", this, SendMessageOptions.DontRequireReceiver);

                return(true);
            }
        }

        return(false);
    }
Ejemplo n.º 2
0
        public LedgeAnchor GetAnchor(float3 position)
        {
            LedgeAnchor result = new LedgeAnchor();

            float3 closestPoint =
                ClosestPoint.FromPosition(position,
                                          vertices[0], vertices[1]);
            float minimumDistance =
                math.length(closestPoint - position);

            result.distance = math.length(closestPoint - vertices[0]);

            int numEdges = vertices.Length;

            for (int i = 1; i < numEdges; ++i)
            {
                closestPoint =
                    ClosestPoint.FromPosition(position,
                                              vertices[i], vertices[GetNextEdgeIndex(i)]);
                float distance =
                    math.length(closestPoint - position);
                if (distance < minimumDistance)
                {
                    minimumDistance = distance;
                    result.index    = i;
                    result.distance =
                        math.length(closestPoint - vertices[i]);
                }
            }

            result.distance = math.clamp(
                result.distance, 0.0f, GetLength(result.index));

            return(result);
        }
Ejemplo n.º 3
0
        public LedgeAnchor UpdateAnchor(LedgeAnchor anchor, float3 position)
        {
            int a = anchor.index;
            int b = GetNextEdgeIndex(anchor.index);

            float3 closestPoint =
                ClosestPoint.FromPosition(position,
                                          vertices[a], vertices[b]);

            LedgeAnchor result;

            float length   = math.length(vertices[b] - vertices[a]);
            float distance = math.length(closestPoint - vertices[a]);

            if (distance > length)
            {
                result.distance = distance - length;
                result.index    = GetNextEdgeIndex(anchor.index);

                return(result);
            }
            else if (distance < 0.0f)
            {
                result.index    = GetPreviousEdgeIndex(anchor.index);
                result.distance = GetLength(result.index) + distance;

                return(result);
            }

            result.distance = distance;
            result.index    = anchor.index;

            return(result);
        }
 //-----------------------------------------------------------------------------------------------------------------
 public static float PointRay(Vector3 P,
                                            // point
                              Vector3 RayO,
                              Vector3 RayD) // ray origin & direction
 {
     return(Vector3.SqrMagnitude(P - ClosestPoint.PointRay(P, RayO, RayD)));
 }
 //-----------------------------------------------------------------------------------------------------------------
 public static float PointSegment(Vector3 P,
                                              // point
                                  Vector3 S0,
                                  Vector3 S1) // end-points of line-segment
 {
     return(Vector3.SqrMagnitude(P - ClosestPoint.PointSegment(P, S0, S1)));
 }
Ejemplo n.º 6
0
    public static AutomorpherRecipe Make(Geometry parentGeometry, Geometry childGeometry)
    {
        var parentLimit0Stencils        = parentGeometry.MakeStencils(StencilKind.LimitStencils, 0);
        var subdivider                  = new Subdivider(parentLimit0Stencils);
        var parentLimit0VertexPositions = subdivider.Refine(parentGeometry.VertexPositions, new Vector3Operators());

        List <(List <WeightedIndex>, Vector3)> resultPairs =
            Enumerable.Range(0, childGeometry.VertexCount)
            .AsParallel().AsOrdered()
            .Select(childVertexIdx => {
            Vector3 graftVertex = childGeometry.VertexPositions[childVertexIdx];
            ClosestPoint.PointOnMesh closestPointOnBaseMesh = ClosestPoint.FindClosestPointOnMesh(parentGeometry.Faces, parentLimit0VertexPositions, graftVertex);

            var merger = new WeightedIndexMerger();
            merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxA), closestPointOnBaseMesh.BarycentricWeights.X);
            merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxB), closestPointOnBaseMesh.BarycentricWeights.Y);
            merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxC), closestPointOnBaseMesh.BarycentricWeights.Z);

            var cloestPointAsVector = closestPointOnBaseMesh.AsPosition(parentLimit0VertexPositions);

            return(merger.GetResult(), cloestPointAsVector);
        })
            .ToList();
        List <List <WeightedIndex> > baseDeltaWeights = resultPairs.Select(t => t.Item1).ToList();

        Vector3[] parentSurfacePositions = resultPairs.Select(t => t.Item2).ToArray();

        var packedBaseDeltaWeights = PackedLists <WeightedIndex> .Pack(baseDeltaWeights);

        return(new AutomorpherRecipe(packedBaseDeltaWeights, parentSurfacePositions));
    }
Ejemplo n.º 7
0
    private RigidBone MapPositionToBone(Vector3 position, ControlVertexInfo[] previousFrameControlVertexInfos)
    {
        Vector3[] previousFrameControlVertexPositions = previousFrameControlVertexInfos.Select(vertexInfo => vertexInfo.position).ToArray();
        int       faceIdx = ClosestPoint.FindClosestFaceOnMesh(inverterParameters.ControlFaces, previousFrameControlVertexPositions, position);
        int       boneIdx = inverterParameters.ControlFaceToBoneMap[faceIdx];
        var       bone    = boneSystem.Bones[boneIdx];

        return(bone);
    }
Ejemplo n.º 8
0
    public static AffineTransform GetClosestTransform(float3 v0, float3 v1, float3 p)
    {
        float3 closestPoint = ClosestPoint.FromPosition(p, v0, v1);

        float3 up   = Missing.up;
        float3 edge = math.normalize(v1 - v0);
        float3 n    = math.cross(edge, up);

        quaternion q = math.quaternion(math.float3x3(-edge, up, -n));

        return(new AffineTransform(closestPoint, q));
    }
Ejemplo n.º 9
0
    // for human agents
    bool CheckHit(Collider inCollider, Vector3 inExplosionPos, ref Vector3 outImpulse)
    {
        Vector3 closestPoint = ClosestPoint.PointBounds(inExplosionPos, inCollider.bounds);

        if (IsCollisionBetween(inExplosionPos, closestPoint, inCollider))
        {
            return(false);
        }

        outImpulse   = inCollider.bounds.center - inExplosionPos;
        outImpulse.y = closestPoint.y - inExplosionPos.y;
        outImpulse.Normalize();
        outImpulse *= m_WeaponImpulse;

        return(true);
    }
    //																																       o
    //Test whether the line intersects (or lies inside) the frustum.																    +-----+
    //NOTE:  For performance reasons we're not doing a precise Intersect/Inside test. The function returns Inside in both cases.	    |/    |
    //FIXME: This function is not accurate, returns outside in case the line crosses corners near the frustum edge!	Something like ->  o+-----+
    public static E_Location LineInFrustumFast(Vector3 lineStart, Vector3 lineEnd)
    {
        //check if any of the line point lies inside
        if (PointInFrustum(lineStart) != E_Location.Outside)
        {
            return(E_Location.Inside);
        }

        if (PointInFrustum(lineEnd) != E_Location.Outside)
        {
            //NOTE: if interested whether the whole line lies Inside, we'd need to check both lineStart and lineEnd before returning...
            return(E_Location.Inside);
        }

        //compute the nearest point between line and camera direction
        Vector3 p = ClosestPoint.PointOfTwoLines(lineStart, lineEnd, CameraPos, CameraPos + CameraDir * Far);

        return(PointInFrustum(p));
    }
Ejemplo n.º 11
0
    // for others
    float ComputeDamage(Collider inVictim, Vector3 inExplosionPos, ref Vector3 outImpulse)
    {
        Vector3 closestPoint = ClosestPoint.PointBounds(inExplosionPos, inVictim.bounds);
        float   distance     = Vector3.Distance(closestPoint, inExplosionPos);

        if ((distance >= damageRadius) || (IsCollisionBetween(inExplosionPos, closestPoint, inVictim) == true))
        {
            return(-1.0f);
        }

        float coef = 1.0f - Mathf.Clamp01(distance / damageRadius);
        float dmg  = BaseDamage * coef;

        outImpulse   = inVictim.bounds.center - inExplosionPos;
        outImpulse.y = closestPoint.y - inExplosionPos.y;
        outImpulse.Normalize();
        outImpulse *= m_WeaponImpulse;

        return(dmg);
    }
Ejemplo n.º 12
0
    private static ClosestPoint CalculateClosestPoint(PathCreator pathCreator, EndOfPathInstruction endOfPath, Vector3 targetPosition)
    {
        var stepScale = pathCreator.path.length % 10;

        stepScale = Mathf.Clamp(stepScale, 1, 500f);
        var          pathStep     = pathCreator.path.length / stepScale;
        ClosestPoint closestPoint = new ClosestPoint(Vector3.zero, -1, 0);

        for (int i = 0; i < stepScale; i++)
        {
            var travelledDistance = pathStep * i;

            var pathPoint      = pathCreator.path.GetPointAtDistance(travelledDistance, endOfPath);
            var vectorToTarget = targetPosition - pathPoint;
            vectorToTarget.y = 0;

            var distanceToTarget = vectorToTarget.magnitude;
            if (distanceToTarget < closestPoint.DistanceToTarget || closestPoint.DistanceToTarget == -1)
            {
                closestPoint = new ClosestPoint(vectorToTarget, distanceToTarget, travelledDistance);
            }
        }
        return(closestPoint);
    }
Ejemplo n.º 13
0
    public override Contact this[int index]
    {
        get
        {
            var contact = Contact.Create(
                startPosition, endPosition);

            contact.shape = null;

            Transform currentTransform = raycastHits[index].collider.transform;

            while (currentTransform != null)
            {
                if (currentTransform == collider.transform)
                {
                    return(contact);
                }

                currentTransform = currentTransform.parent;
            }

            contact.contact         = raycastHits[index];
            contact.contactCollider = raycastHits[index].collider;
            contact.contactPoint    = raycastHits[index].point;
            contact.contactNormal   = raycastHits[index].normal;
            contact.contactDistance = raycastHits[index].distance;

            if (raycastHits[index].distance == 0f)
            {
                var(linePoint, colliderPoint) =
                    ClosestPoint.FromLineSegment(
                        contact.startPosition, contact.endPosition,
                        contact.contactCollider, layerMask);

                if (Missing.IsNaN(colliderPoint))
                {
                    return(contact);
                }

                var delta = colliderPoint - linePoint;

                contact.contactOrigin = linePoint;
                contact.contactPoint  = colliderPoint;

                contact.contactDistance    = math.length(delta) - Radius;
                contact.contactPenetration = (contact.contactDistance < 0f);

                RaycastHit raycastHit;
                if (Raycast.ClosestHit(
                        linePoint, math.normalizesafe(delta), out raycastHit,
                        math.max(contact.contactDistance + Radius, Radius + 0.01f)))
                {
                    contact.contactNormal = raycastHit.normal;
                }
                else if (contact.contactDistance < epsilon)
                {
                    contact.contactNormal =
                        math.normalizesafe(linePoint - colliderPoint);
                }
            }
            else
            {
                contact.contactOrigin = ClosestPoint.FromPosition(
                    contact.contactPoint, contact.startPosition, contact.endPosition);
            }

            contact.contactNormal = math.normalizesafe(contact.contactOrigin - contact.contactPoint);

            contact.shape = this;

            return(contact);
        }
    }
Ejemplo n.º 14
0
 public override float3 FromPosition(float3 position, float3 origin)
 {
     return(ClosestPoint.FromPosition(origin, Bottom(position), Top(position), Radius));
 }
Ejemplo n.º 15
0
    void InitializeSupport(float3 position)
    {
        var rayStartPosition = position + (math.up() * groundProbeOffset);
        var rayDirection     = -math.up();
        var rayLength        = groundProbeOffset + groundProbeLength;

        RaycastHit raycast;

        bool isGrounded = Raycast.ClosestHit(
            rayStartPosition, rayDirection, out raycast,
            rayLength, layerMask, transform);

        if (isGrounded)
        {
            isGrounded           = (raycast.distance - groundProbeOffset < groundTolerance + epsilon);
            state.current.ground = raycast.collider.gameObject.transform;
            rayLength            = raycast.distance + groundSupport;
        }

        if (!isGrounded)
        {
            float3 closestPoint = raycast.point;

            rayStartPosition = position + (math.up() * groundSupport);

            Collider[] colliders = null;

            var numContacts = Intersection.OverlapSphere(
                rayStartPosition, groundSupport * oneOverCos45,
                out colliders, layerMask, transform);

            bool ignore = false;

            if (colliders == null || numContacts == 0)
            {
                ignore     = true;
                isGrounded = false;
            }
            else if (numContacts == 1)
            {
                var result = ClosestPoint.FromPosition(
                    rayStartPosition, colliders[0]);

                if (!Missing.IsNaN(result))
                {
                    closestPoint = result;

                    var closestPointLocal =
                        state.current.InverseTransformPoint(
                            closestPoint);

                    closestPointLocal.y = 0f;

                    if (closestPointLocal.magnitude > (groundSupport * 0.25f))
                    {
                        ignore     = true;
                        isGrounded = false;
                    }
                }
            }
            else
            {
                for (int i = 0; i < numContacts; i++)
                {
                    if (colliders[i] == raycast.collider)
                    {
                        continue;
                    }

                    var candidatePoint = ClosestPoint.FromPosition(
                        rayStartPosition, colliders[i]);

                    if (Missing.IsNaN(candidatePoint))
                    {
                        continue;
                    }

                    var candidatePointLocal = state.current.InverseTransformPoint(candidatePoint);

                    if (candidatePointLocal.y >= groundSupport + epsilon)
                    {
                        continue;
                    }

                    if (-candidatePointLocal.y > groundTolerance + epsilon)
                    {
                        continue;
                    }

                    candidatePointLocal.y = 0f;

                    if (math.length(candidatePointLocal) < (groundSupport * 0.25f))
                    {
                        closestPoint = candidatePoint;

                        isGrounded = true;

                        break;
                    }
                }
            }

            if (!ignore)
            {
                var closestPointToRayStart = closestPoint - rayStartPosition;

                rayDirection = math.normalizesafe(closestPointToRayStart);
                rayLength    = math.length(closestPointToRayStart) + groundTolerance;

                var rayCastResult = Raycast.ClosestHit(
                    rayStartPosition, rayDirection, out raycast,
                    rayLength, layerMask, transform);

                if (rayCastResult)
                {
                    float groundDistance = raycast.distance - groundSupport;
                    isGrounded           = groundDistance < (groundTolerance + epsilon) * oneOverCos45;
                    state.current.ground = raycast.collider.gameObject.transform;
                }
            }
        }

        state.current.isGrounded = isGrounded;
    }
Ejemplo n.º 16
0
    float GetGroundDistance(float3 position)
    {
        var rayStartPosition = position + (math.up() * groundProbeOffset);
        var rayDirection     = -math.up();
        var rayLength        = groundProbeOffset + groundProbeLength;

        bool isGrounded = false;

        RaycastHit raycast;

        var rayCastResult = Raycast.ClosestHit(
            rayStartPosition, rayDirection, out raycast,
            rayLength, layerMask, transform);

        var distance = float.MaxValue;

        if (rayCastResult)
        {
            var tolerance = (groundSnap ? groundSnapDistance : groundTolerance);

            isGrounded           = raycast.distance - groundProbeOffset < tolerance + epsilon;
            distance             = raycast.distance - groundProbeOffset;
            state.current.ground = raycast.collider.transform;
        }

        if (!isGrounded)
        {
            float3 closestPoint = raycast.point;

            rayStartPosition = position + (math.up() * groundSupport);

            Collider[] colliders = null;

            int numContacts = Intersection.OverlapSphere(
                rayStartPosition, groundSupport * oneOverCos45,
                out colliders, layerMask, transform);

            bool ignore = false;

            if (colliders == null || numContacts == 0)
            {
                ignore     = true;
                isGrounded = false;
            }
            else if (numContacts == 1)
            {
                var result = ClosestPoint.FromPosition(
                    position + math.up() * 0.05f, colliders[0]);

                if (!Missing.IsNaN(result))
                {
                    closestPoint = result;

                    var closestPointLocal =
                        state.current.InverseTransformPoint(closestPoint);

                    closestPointLocal.y = 0f;

                    if (closestPointLocal.magnitude < groundSupport)
                    {
                        ignore     = false;
                        isGrounded = true;
                    }
                    else
                    {
                        ignore     = true;
                        isGrounded = false;
                    }
                }
            }
            else
            {
                for (int i = 0; i < numContacts; i++)
                {
                    if (colliders[i] == raycast.collider)
                    {
                        continue;
                    }

                    var candidatePoint = ClosestPoint.FromPosition(
                        position + math.up() * 0.05f, colliders[i]);

                    if (Missing.IsNaN(candidatePoint))
                    {
                        continue;
                    }

                    var candidatePointLocal = state.current.InverseTransformPoint(candidatePoint);

                    if (candidatePointLocal.y >= groundSupport + epsilon)
                    {
                        continue;
                    }

                    candidatePointLocal.y = 0f;

                    if (math.length(candidatePointLocal) < groundSupport)
                    {
                        closestPoint = candidatePoint;

                        isGrounded = true;

                        break;
                    }
                }
            }

            if (!ignore)
            {
                var closestPointLocal = state.current.InverseTransformPoint(closestPoint);

                rayStartPosition = closestPoint + (math.up() * groundSupport);

                rayDirection = -math.up();
                rayLength    = groundSupport + groundTolerance;

                rayCastResult = Raycast.ClosestHit(
                    rayStartPosition, rayDirection, out raycast,
                    rayLength, layerMask, transform);

                if (rayCastResult)
                {
                    distance             = raycast.distance - groundSupport - closestPointLocal.y;
                    isGrounded           = distance < (groundTolerance + epsilon) * oneOverCos45;
                    state.current.ground = raycast.collider.gameObject.transform;
                }
            }
        }

        return(distance);
    }
Ejemplo n.º 17
0
        private static void Knn_OnClassify(Point2D NewNode, IEnumerable <Point2D> ClosestKPoints, string MostTag, IEnumerable <Point2D> ClassifiedNodes)
        {
            Console.WriteLine("NewPoint,x:{0},y:{1}\t,closet points in {2}", NewNode.x, NewNode.y, k);

            foreach (var ClosestPoint in ClosestKPoints)
            {
                Console.WriteLine("Point,x:{0},y:{1}\t,tag:{2},distance{3}", ClosestPoint.x, ClosestPoint.y, ClosestPoint.Tag, ClosestPoint.GetEuclideanDistance(NewNode));
            }

            Console.WriteLine("MostTag:{0}", MostTag);
            Console.WriteLine("----------------------------------");

            List <Point2D> point2Ds = new List <Point2D>();

            point2Ds.AddRange(ClassifiedNodes);

            StringBuilder sb = new StringBuilder();

            sb.Append("Round:");
            sb.Append(Round++);
            sb.Append(" ,AddPoint At:");
            sb.Append(NewNode.x);
            sb.Append(",");
            sb.Append(NewNode.y);
            sb.Append(",Tag:");
            sb.Append(NewNode.Tag);
            Points2DCollectionsViewer View = Points2DCollectionsViewer.BuildViewer(point2Ds, sb.ToString(), 0, NodesMaxValueSet);

            View.AddMarkAt(NewNode, 20, 7);

            foreach (var ClosestPoint in ClosestKPoints)
            {
                View.AddMarkAt(ClosestPoint, 6, 7);
            }
            Points2DCollectionsViewer.ShowViewer(View);
        }
Ejemplo n.º 18
0
    public override Contact this[int index]
    {
        get
        {
            var contact = Contact.Create(
                startPosition, float3.zero);

            contact.shape = null;

            Transform currentTransform = raycastHits[index].collider.transform;
            if (currentTransform == collider.transform)
            {
                return(contact);
            }

            while (currentTransform != null)
            {
                if (currentTransform == collider.transform)
                {
                    return(contact);
                }

                currentTransform = currentTransform.parent;
            }

            contact.contact         = raycastHits[index];
            contact.contactOrigin   = contact.startPosition;
            contact.contactCollider = raycastHits[index].collider;
            contact.contactPoint    = raycastHits[index].point;
            contact.contactNormal   = raycastHits[index].normal;

            contact.contactDistance = raycastHits[index].distance;

            if (raycastHits[index].distance == 0f)
            {
                var colliderPoint = ClosestPoint.FromPosition(contact.startPosition, contact.contactCollider, layerMask);

                if (Missing.IsNaN(colliderPoint))
                {
                    return(contact);
                }

                float3 delta = colliderPoint - contact.startPosition;
                if (math.abs(math.length(delta) - Radius) < epsilon)
                {
                    float dot = math.dot(math.normalizesafe(delta), direction);
                    if (dot <= -0.8f)
                    {
                        return(contact);
                    }
                }

                contact.contactOrigin = contact.startPosition;
                contact.contactPoint  = colliderPoint;

                contact.contactDistance    = math.length(delta) - Radius;
                contact.contactPenetration = (contact.contactDistance < 0f);

                RaycastHit raycastHit;
                if (Raycast.ClosestHit(contact.startPosition, math.normalizesafe(delta),
                                       out raycastHit, Mathf.Max(contact.contactDistance + Radius, Radius + 0.01f)))
                {
                    contact.contactNormal = raycastHit.normal;
                }
                else if (contact.contactDistance < epsilon)
                {
                    contact.contactNormal = math.normalizesafe(contact.startPosition - colliderPoint);
                }
            }

            if (!Missing.equalEps(direction, -Missing.up, epsilon))
            {
                RaycastHit raycastHit;
                if (Raycast.ClosestHit(contact.contactPoint - (direction * distance),
                                       direction, out raycastHit, distance + Radius, -1, collider.transform))
                {
                    contact.contactNormal = raycastHit.normal;
                }
            }

            contact.shape = this;

            return(contact);
        }
    }