예제 #1
0
    // Credit
    // http://wiki.unity3d.com/index.php/3d_Math_functions
    // http://creativecommons.org/licenses/by-sa/3.0/
    public static bool ClosestPointsOnTwoLines(out Vector3 closestPointLine1, out Vector3 closestPointLine2, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2)
    {
        closestPointLine1 = Vector3.zero;
        closestPointLine2 = Vector3.zero;

        float a = Vector3.Dot(lineVec1, lineVec1);
        float b = Vector3.Dot(lineVec1, lineVec2);
        float e = Vector3.Dot(lineVec2, lineVec2);

        float d = a * e - b * b;

        //lines are not parallel
        if (d != 0.0f)
        {
            Vector3 r = linePoint1 - linePoint2;
            float   c = Vector3.Dot(lineVec1, r);
            float   f = Vector3.Dot(lineVec2, r);

            float s = (b * f - c * e) / d;
            float t = (a * f - c * b) / d;

            closestPointLine1 = linePoint1 + lineVec1 * s;
            closestPointLine2 = linePoint2 + lineVec2 * t;

            return(true);
        }
        else
        {
            return(false);
        }
    }
예제 #2
0
    private void Update()
    {
        var desired = (Enemy.Instance.transform.position - transform.position).normalized;

        PreviewRay(desired, Color.blue);
        desired = AvoidWalls(desired);
        PreviewRay(desired, Color.yellow);
        var anglebetween = Mathf.Acos(Vector3.Dot(desired, heading)) * Mathf.Rad2Deg;
        var maxAngle     = maxAngularSpeed * Time.deltaTime * Mathf.Deg2Rad;

        if (anglebetween <= maxAngle)
        {
            heading = desired.normalized;
        }
        else
        {
            var normal = Vector2.Dot(new Vector2(-heading.y, heading.x), desired);
            if (normal < 0)
            {
                maxAngle *= -1;
            }

            heading =
                new Vector3(
                    heading.x * Mathf.Cos(maxAngle) - heading.y * Mathf.Sin(maxAngle),
                    heading.x * Mathf.Sin(maxAngle) + heading.y * Mathf.Cos(maxAngle))
                .normalized;
        }

        UpdateOrientation();

        transform.position += new Vector3(heading.x, heading.y) * maxSpeed * Time.deltaTime;
    }
예제 #3
0
    private void MovePlayer(float translation, float rotation)
    {
        if (_navMeshAgent.isOnOffMeshLink)
        {
            _navMeshAgent.CompleteOffMeshLink();
            companion.GetComponent <NavMeshAgent>().Warp(teleportLocation.position);
            MusicController.GetInstance().variation = MusicController.Variation.C_NoLowpass;
        }
        Vector3 velocityForward   = transform.forward * translation;
        Vector3 velocitySideways  = transform.right * rotation;
        Vector3 resultantVelocity = velocityForward + velocitySideways;
        Vector3 destination       = resultantVelocity + transform.position;

        if (_isHeldBack)
        {
            Vector3 destFlat           = new Vector3(destination.x, 0, destination.z).normalized;
            Vector3 companionDirection = (companion.transform.position - transform.position).normalized;
            Vector3 companionFlat      = new Vector3(companionDirection.x, 0, companionDirection.z);
            float   dot = Vector3.Dot(destFlat, companionFlat);
            if (dot < -0.5f)
            {
                return;
            }
        }

        _navMeshAgent.speed          = resultantVelocity.magnitude;
        _navMeshAgent.velocity       = resultantVelocity;
        _navMeshAgent.updateRotation = translation > 0.0f || Math.Abs(rotation) > 0.0f;
        _navMeshAgent.SetDestination(destination);
    }
예제 #4
0
    // Credit
    // http://wiki.unity3d.com/index.php/3d_Math_functions
    // http://creativecommons.org/licenses/by-sa/3.0/
    //This function finds out on which side of a line segment the point is located.
    //The point is assumed to be on a line created by linePoint1 and linePoint2. If the point is not on
    //the line segment, project it on the line using ProjectPointOnLine() first.
    //Returns 0 if point is on the line segment.
    //Returns 1 if point is outside of the line segment and located on the side of linePoint1.
    //Returns 2 if point is outside of the line segment and located on the side of linePoint2.
    public static int PointOnWhichSideOfLineSegment(Vector3 linePoint1, Vector3 linePoint2, Vector3 point)
    {
        Vector3 lineVec  = linePoint2 - linePoint1;
        Vector3 pointVec = point - linePoint1;

        float dot = Vector3.Dot(pointVec, lineVec);

        //point is on side of linePoint2, compared to linePoint1
        if (dot > 0)
        {
            //point is on the line segment
            if (pointVec.magnitude <= lineVec.magnitude)
            {
                return(0);
            }

            //point is not on the line segment and it is on the side of linePoint2
            else
            {
                return(2);
            }
        }

        //Point is not on side of linePoint2, compared to linePoint1.
        //Point is not on the line segment and it is on the side of linePoint1.
        else
        {
            return(1);
        }
    }
예제 #5
0
        public void Execute(int index)
        {
            int triIndex = index * 3;

            var v1 = rotation * Vec3.Scale(vertices[triangles[triIndex]], localScale) + position;
            var v2 = rotation * Vec3.Scale(vertices[triangles[triIndex + 1]], localScale) + position;
            var v3 = rotation * Vec3.Scale(vertices[triangles[triIndex + 2]], localScale) + position;

            var tri = new Triangle(v1, v2, v3);

            // calculate the angle of this triangles resistance
            var cosAngle = Vec3.Dot(tri.Normal, -velocity) / (velocity.magnitude * tri.Normal.magnitude);
            var angle    = Mathf.Acos(cosAngle);

            // magnitude of drag: 180 = 1, 135 = 0.5, < 90 = 0
            angleMags[index] = Mathf.Clamp((angle - Mathf.PI / 2) / (Mathf.PI / 2), 0, 1);

            var velSqu = Mathf.Pow(velocity.magnitude, 2);

            if (useSimpleDrag)
            {
                dragForces[index] = -.5f * velSqu * tri.Area * (angleMags[index] * dragMulti) * Vec3.Normalize(velocity);
            }
            else
            {
                dragForces[index] = -.5f * velSqu * tri.Area * (angleMags[index] * dragMulti) * Vec3.Normalize(tri.Normal);
            }

            midpoints[index] = tri.Midpoint;
        }
예제 #6
0
    private bool GJK(Prism prismA, Prism prismB)
    {
        pointList = new List <Vector3>();
        // Start at a random point
        dir = new Vector3(1, 1, 1);
        pointList.Add(getSupport(prismA, prismB, dir));

        dir = -pointList[0];
        var count = 0;

        while (count < 50)
        {
            count++;
            pointList.Add(getSupport(prismA, prismB, dir));

            if (Vector3.Dot(pointList[pointList.Count - 1], dir) < 0)
            {
                pointList.Clear();
            }

            if (OinSimplex(prismA, prismB))
            {
                return(true);
            }
        }
        return(false);
    }
예제 #7
0
        public bool Contains(Vector3 point)
        {
            // Transform to local space (shape in the XZ plane)
            point -= origin;
            var localSpacePoint = new Vector3(Vector3.Dot(point, right) / right.sqrMagnitude, 0, Vector3.Dot(point, forward) / forward.sqrMagnitude);

            if (convex)
            {
                if (_convexPoints == null)
                {
                    return(false);
                }

                for (int i = 0, j = _convexPoints.Length - 1; i < _convexPoints.Length; j = i, i++)
                {
                    if (VectorMath.RightOrColinearXZ(_convexPoints[i], _convexPoints[j], localSpacePoint))
                    {
                        return(false);
                    }
                }
                return(true);
            }
            else
            {
                return(_points != null && Polygon.ContainsPointXZ(_points, localSpacePoint));
            }
        }
예제 #8
0
    void LateUpdate()
    {
        for (int i = 0; i < _trackedTravellers.Count; i++)
        {
            PortalTraveller traveller  = _trackedTravellers[i];
            Transform       travellerT = traveller.transform;
            Matrix4x4       m          = otherPortal.transform.localToWorldMatrix * transform.worldToLocalMatrix * travellerT.localToWorldMatrix;

            Vector3 offsetFromPortal = travellerT.position - transform.position;
            int     portalSide       = Math.Sign(Vector3.Dot(offsetFromPortal, transform.forward));
            int     portalSideOld    = Math.Sign(Vector3.Dot(traveller.prevOffsetFromPortal, transform.forward));
            // Teleport the traveller if it has crossed from one side of the portal to the other
            if (portalSide != portalSideOld)
            {
                traveller.Teleport(transform, otherPortal.transform, m.GetColumn(3), m.rotation);
                // Can't rely on OnTriggerEnter/Exit to be called next frame since it depends on when FixedUpdate runs
                otherPortal.OnTravellerEnterPortal(traveller);
                _trackedTravellers.RemoveAt(i);
                i--;
            }
            else
            {
                traveller.prevOffsetFromPortal = offsetFromPortal;
            }
        }
    }
예제 #9
0
    protected void RotateSlice(List <GameObject> slice, float angleInDeg)
    {
        Vector3 axis = (m_shuffleCoroutine != null || m_solveCoroutine != null) ?
                       transform.TransformVector(m_selectedPlane
                                                 .normal) : m_selectedPlane
                       .normal;

        Vector3 point = m_selectedPlane.distance * axis;

        for (int i = 0; i < slice.Count; i++)
        {
            Vector3 position = slice[i].transform.position;
            slice[i].transform.position = point + Quaternion.AngleAxis(angleInDeg, axis) * (position - point);
            slice[i].transform.rotation = Quaternion.AngleAxis(angleInDeg, axis) * slice[i].transform.rotation;
        }

        Vector3 up = Mathf.Abs(Vector3.Dot(slice.Last().transform.up, axis)) < 0.5f
            ? slice.Last().transform.up
            : Mathf.Abs(Vector3.Dot(slice.Last().transform.right, axis)) < 0.5f
                ? slice.Last().transform.right
                : slice.Last().transform.forward;

        m_NeutralPlaneSlice1.transform.rotation = Quaternion.LookRotation(-axis, up);
        m_NeutralPlaneSlice2.transform.rotation = Quaternion.LookRotation(axis, up);
    }
예제 #10
0
        public static float CalculateTurn(Quaternion originalRotation, Quaternion transformRotation)
        {
            var cross = Vector3.Cross(originalRotation * Vector3.forward, transformRotation * Vector3.forward);
            var dot   = Vector3.Dot(cross, Vector3.up);

            return(dot);
        }
예제 #11
0
        private void UpdateRpm()
        {
            var forwardVelocity = Vector3.Dot(velocity, transform.forward);
            var rotPerSec       = forwardVelocity / (2 * Mathf.PI * _wheel.GetRadius());

            _rpm = rotPerSec * 60;
        }
예제 #12
0
    protected void FillSliceVoidWithNeutralPlane()
    {
        Vector3 axis = (m_shuffleCoroutine != null || m_solveCoroutine != null) ? transform.TransformVector(m_selectedPlane.normal) : m_selectedPlane
                       .normal;

        if (m_selectedPlane.distance < (0.5f * m_width - 0.5f))
        {
            m_NeutralPlaneRubix2.SetActive(true);
            m_NeutralPlaneSlice2.SetActive(true);
        }

        if (m_selectedPlane.distance > -(0.5f * m_width - 0.5f))
        {
            m_NeutralPlaneRubix1.SetActive(true);
            m_NeutralPlaneSlice1.SetActive(true);
        }

        m_NeutralPlaneRubix1.transform.position     =
            m_NeutralPlaneSlice1.transform.position = axis * -(m_selectedPlane.distance - 0.5f);

        m_NeutralPlaneRubix2.transform.position     =
            m_NeutralPlaneSlice2.transform.position = axis * -(m_selectedPlane.distance + 0.5f);

        Vector3 up = Mathf.Abs(Vector3.Dot(transform.up, axis)) < 0.5f
            ? transform.up
            : Mathf.Abs(Vector3.Dot(transform.right, axis)) < 0.5f ? transform.right : transform.forward;

        m_NeutralPlaneRubix2.transform.rotation     =
            m_NeutralPlaneSlice2.transform.rotation = Quaternion.LookRotation(-axis, up);

        m_NeutralPlaneRubix1.transform.rotation     =
            m_NeutralPlaneSlice1.transform.rotation = Quaternion.LookRotation(axis, up);
    }
예제 #13
0
    private bool OinSimplex(Prism prismA, Prism prismB)
    {
        switch (pointList.Count)
        {
        case 2:
            if (Vector3.Dot(pointList[0] - pointList[1], -pointList[1]) > 0)
            {
                // AB x AO x AB
                // Origin is in between A and B
                dir = Vector3.Cross(Vector3.Cross(pointList[0] - pointList[1], -pointList[1]), pointList[0] - pointList[1]);
                return(false);
            }
            else
            {
                pointList.RemoveAt(0);
                dir = -pointList[0];
                return(false);
            }

        case 3:
            return(triangle(prismA, prismB));

        case 4:
            return(tetrahedron(prismA, prismB));

        default:
            return(false);
        }
    }
    void SphereMovementVectors()
    {
        //THESE VECTORS LENGTH ISNT  2 (SPEED)!
        sphere1BlueInitialVelo = sphereBlueVeloAccess.sphereVelocity; //sphere1Blue.transform.forward * speed * Time.deltaTime;
        Debug.DrawRay(sphere1Blue.transform.position, sphere1Blue.transform.forward * speed, Color.blue);
        sphere2RedInitialVelo = sphereRedVeloAccess.sphereVelocity;   //sphere2Red.transform.forward * speed * Time.deltaTime;
        Debug.DrawRay(sphere2Red.transform.position, sphere2Red.transform.forward * speed, Color.red);
        //Dir = target.Pos - current.Pos
        Vector3 dir2BlueS = (sphere1Blue.transform.position - sphere2Red.transform.position).normalized;   //normalize?

        Debug.DrawRay(sphere2Red.transform.position, dir2BlueS.normalized * 1, Color.red);
        Vector3 dir2RedS = (sphere2Red.transform.position - sphere1Blue.transform.position).normalized;    //normalize?

        Debug.DrawRay(sphere1Blue.transform.position, dir2RedS.normalized * 1, Color.blue);
        //======================================================================================================
        Vector3 blueSphereHypo = sphere1BlueInitialVelo;
        Vector3 collisionDir   = dir2RedS.normalized;
        float   blueA1         = Vector3.Dot(blueSphereHypo, collisionDir);     // length of the component of each of the movement vectors along the dir
        Vector3 redSphereHypo  = sphere2RedInitialVelo;
        //Vector3 redSphereDir = dir2BlueS.normalized;
        float   redA2     = Vector3.Dot(redSphereHypo, collisionDir); //redSphereDir);
        float   P         = (2 * (blueA1 - redA2)) / (1 + 1);
        Vector3 blueNewV1 = blueSphereHypo - P * 1 * collisionDir;    //redSphereDir;
        Vector3 redNewV1  = redSphereHypo + P * 1 * collisionDir;

        //======================================================================================================
        sphereRedVeloAccess.sphereVelocity  = redNewV1;
        sphereBlueVeloAccess.sphereVelocity = blueNewV1;
    }
    public int BestPlaneAxis()
    {
        Vector3 viewDir = Camera.main.transform.forward;
        Vector3 molDir  = moleculeSpace.transform.forward;

        return((Mathf.Abs(Vector3.Dot(viewDir, molDir)) < 0.8f) ? 0 : 2);
    }
예제 #16
0
    // Credit
    // http://wiki.unity3d.com/index.php/3d_Math_functions
    // http://creativecommons.org/licenses/by-sa/3.0/
    //This function returns a point which is a projection from a point to a line.
    //The line is regarded infinite. If the line is finite, use ProjectPointOnLineSegment() instead.
    public static Vector3 ProjectPointOnLine(Vector3 linePoint, Vector3 lineVec, Vector3 point)
    {
        //get vector from point on line to point in space
        Vector3 linePointToPoint = point - linePoint;

        float t = Vector3.Dot(linePointToPoint, lineVec);

        return(linePoint + lineVec * t);
    }
예제 #17
0
    private Vector3 EPA_3d(Prism prismA, Prism prismB)
    {
        var n        = pointList.Count();
        var minDist  = float.MaxValue;
        var prevDist = 0f;

        Tuple <Vector3, Vector3, Vector3> closestPlane = null;
        Vector3 support = Vector3.zero;
        var     normal  = Vector3.zero;

        List <Tuple <Vector3, Vector3, Vector3> > simplex = new List <Tuple <Vector3, Vector3, Vector3> >();

        for (var i = 0; i < n; i++)
        {
            for (var j = i + 1; j < n; j++)
            {
                for (var k = j + 1; k < n; k++)
                {
                    simplex.Add(new Tuple <Vector3, Vector3, Vector3>(pointList[i], pointList[j], pointList[k]));
                }
            }
        }

        while (Mathf.Abs(prevDist - minDist) > 0.01f)
        {
            // DrawSimplex(simplex);
            prevDist = minDist;

            foreach (var plane in simplex)
            {
                // normal to the plane
                normal = Vector3.Cross(plane.Item2 - plane.Item1, plane.Item3 - plane.Item1).normalized;
                // projecttion of AO vector on this normal is the distance of Origin from the plane)
                float distanceFromOrigin = Vector3.Dot(normal, -plane.Item1);

                if (distanceFromOrigin < minDist)
                {
                    minDist      = distanceFromOrigin;
                    closestPlane = plane;
                }
            }

            // find normal to this vector in the outward direction (away from origin)
            normal = -normal;
            // find support point on minkowski in the direction of this normal vector
            support = getSupport(prismA, prismB, normal);

            // remove this plane and 3 more to the list
            simplex.Remove(closestPlane);
            simplex.Add(new Tuple <Vector3, Vector3, Vector3>(closestPlane.Item1, closestPlane.Item2, support));
            simplex.Add(new Tuple <Vector3, Vector3, Vector3>(closestPlane.Item1, closestPlane.Item3, support));
            simplex.Add(new Tuple <Vector3, Vector3, Vector3>(closestPlane.Item2, closestPlane.Item3, support));
        }

        return(support);
    }
        /// <summary>Calcule distance minimum entre les deux droites</summary>
        public static float Dist(Line x, Line y)
        {
            Point n = Point.Cross(x.direction.normalized, y.direction.normalized);

            if (n.magnitude == 0) // if parallel
            {
                return(Dist(x, y.origin));
            }
            return(Mathf.Abs(Point.Dot(n.normalized, (y.origin - x.origin))));
        }
        /// <summary>Calcule la distance signée entre une droite et un plan. Le signe dépend du côté duquel se trouve la droite par rapport au plan. Vaut 0 si ils ne sont pas parallèles.</summary>
        public static float DistSigned(Plane p, Line l)
        {
            Point d = l.direction, n = p.normal;

            if (Point.Dot(d, n) == 0) // plane parallel to ray
            {
                return(DistSigned(p, l.origin));
            }
            return(0);
        }
예제 #20
0
    float FCT_BBSK(Vector3 pos)
    {
        Vector3 cFcParams = new Vector3(2.18f, -0.18f, 0);
        Vector3 CSize     = new Vector3(1.4f, 0.87f, 1.1f);
        Vector3 p;

        p.x = 2 * pos.x;
        p.y = 2 * pos.z;
        p.z = 2 * pos.y;
        float scale = 1.0f;

        for (int i = 0; i < 4; i++)
        {
            p.x = 2 * Mathf.Clamp(p.x, -CSize.x, CSize.x) - p.x;
            p.y = 2 * Mathf.Clamp(p.y, -CSize.y, CSize.y) - p.y;
            p.z = 2 * Mathf.Clamp(p.z, -CSize.z, CSize.x) - p.z;
            float r2 = Vector3.Dot(p, p);
            //float r2 = dot(p,p+sin(p.z*.5)); //Alternate fractal
            float k = Mathf.Max((2f) / (r2), .17f);
            p *= k;
            //p *=rot;
            //p= p.yzx;
            p     += new Vector3(0.2f, 0.2f, -0.5f);
            scale *= k;
        }

        p.x = 2 * Mathf.Clamp(p.x, -CSize.x * 4, CSize.x * 4) - p.x;
        p.y = 2 * Mathf.Clamp(p.y, -CSize.y * 4, CSize.y * 4) - p.y;
        p.z = 2 * Mathf.Clamp(p.z, -CSize.z * 4, CSize.x * 4) - p.z;

        for (int i = 0; i < 8; i++)
        {
            p.x = 2 * Mathf.Clamp(p.x, -CSize.x, CSize.x) - p.x;
            p.y = 2 * Mathf.Clamp(p.y, -CSize.y, CSize.y) - p.y;
            p.z = 2 * Mathf.Clamp(p.z, -CSize.z, CSize.x) - p.z;
            float r2 = Vector3.Dot(p, p);
            //float r2 = dot(p,p+sin(p.z*.3)); //Alternate fractal
            float k = Math.Max((cFcParams.x) / (r2), 0.027f);
            p     *= k;
            scale *= k;
            p.y   += cFcParams.y;
        }

        float l = Mathf.Sqrt(Vector2.SqrMagnitude(new Vector2(p.x, p.y)));
        //l = mix(l,l2,0.5);
        float rxy = l - 4;
        float n   = p.z;

        rxy = Math.Max(rxy, -(n) / 4);
        float dist = (rxy) / Math.Abs(scale);

        dist *= .75f;

        return(dist);
    }
예제 #21
0
    private Vector3 DampenVelocity(ParticleCollider particleCollider, Vector3 velocity, Vector3 penetrationNormal, float drag)
    {
        Vector3 newVelocity = Vector3.Dot(velocity, penetrationNormal) * _damping * penetrationNormal +
                              Vector3.Dot(velocity, particleCollider.Right) *
                              drag * particleCollider.Right + Vector3.Dot(velocity, particleCollider.Up) *
                              Drag * particleCollider.Up;

        return(Vector3.Dot(newVelocity, Vector3.forward) * Vector3.forward +
               Vector3.Dot(newVelocity, Vector3.right) * Vector3.right +
               Vector3.Dot(newVelocity, Vector3.up) * Vector3.up);
    }
예제 #22
0
        /** True if the matrix will reverse orientations of faces.
         *
         * Scaling by a negative value along an odd number of axes will reverse
         * the orientation of e.g faces on a mesh. This must be counter adjusted
         * by for example the recast rasterization system to be able to handle
         * meshes with negative scales properly.
         *
         * We can find out if they are flipped by finding out how the signed
         * volume of a unit cube is transformed when applying the matrix
         *
         * If the (signed) volume turns out to be negative
         * that also means that the orientation of it has been reversed.
         *
         * \see https://en.wikipedia.org/wiki/Normal_(geometry)
         * \see https://en.wikipedia.org/wiki/Parallelepiped
         */
        public static bool ReversesFaceOrientations(Matrix4x4 matrix)
        {
            var dX = matrix.MultiplyVector(new Vector3(1, 0, 0));
            var dY = matrix.MultiplyVector(new Vector3(0, 1, 0));
            var dZ = matrix.MultiplyVector(new Vector3(0, 0, 1));

            // Calculate the signed volume of the parallelepiped
            var volume = Vector3.Dot(Vector3.Cross(dX, dY), dZ);

            return(volume < 0);
        }
예제 #23
0
    void OnControllerColliderHit(ControllerColliderHit hit)
    {
        if (hit.collider)
        {
            velocity -= Vector3.Dot(velocity, hit.normal) * hit.normal;

            if (Vector3.Dot(Vector3.up, hit.normal) >= minVerticalGroundNormal)
            {
                groundNormal = hit.normal;
            }
        }
    }
예제 #24
0
    private bool CheckCollision(ParticleCollider particleCollider, Vector3 position, float radius, out Vector3 penetrationNormal, out Vector3 penetrationPosition, out float penetrationLength)
    {
        Vector3 colliderProjection = particleCollider.Position - position;

        penetrationNormal   = Vector3.Cross(particleCollider.Right, particleCollider.Up);
        penetrationLength   = Mathf.Abs(Vector3.Dot(colliderProjection, penetrationNormal)) - (radius / 2.0f);
        penetrationPosition = particleCollider.Position - colliderProjection;

        return(penetrationLength < 0.0f &&
               Mathf.Abs(Vector3.Dot(colliderProjection, particleCollider.Right)) < particleCollider.Scale.x &&
               Mathf.Abs(Vector3.Dot(colliderProjection, particleCollider.Up)) < particleCollider.Scale.y);
    }
예제 #25
0
    private bool isLookAtTarget(MyObject currentTarget)
    {
        Vector3 dirFromAtoB = (currentTarget.transform.position - transform.position).normalized;
        float   dotProd     = Vector3.Dot(dirFromAtoB, transform.forward);

        if (dotProd > facingThreshold)
        {
            return(true);
        }

        return(false);
    }
예제 #26
0
    private Vector3 EPA_2D(Prism prismA, Prism prismB)
    {
        var n = pointList.Count();

        var minDist  = float.MaxValue;
        var prevDist = 0f;

        Tuple <Vector3, Vector3> closestSide = null;
        Vector3 support = Vector3.zero;
        var     normal  = Vector3.zero;

        List <Tuple <Vector3, Vector3> > simplex = new List <Tuple <Vector3, Vector3> >();


        for (var i = 0; i < n; i++)
        {
            simplex.Add(new Tuple <Vector3, Vector3>(pointList[i], pointList[(i + 1) % n]));
        }

        while (Mathf.Abs(prevDist - minDist) > 0.01f)
        {
            // DrawSimplex(simplex);
            prevDist = minDist;
            foreach (var side in simplex)
            {
                float distanceFromOrigin = Vector3.Cross(side.Item2 - side.Item1, -side.Item1).magnitude;
                if (distanceFromOrigin < minDist)
                {
                    minDist     = distanceFromOrigin;
                    closestSide = side;
                }
            }

            // find normal to this vector in the outward direction (away from origin)
            var direction = closestSide.Item2 - closestSide.Item1;
            normal = new Vector3(-direction.z, 0f, direction.x);
            if (Vector3.Dot(normal, -closestSide.Item1) > 0)
            {
                normal = -normal;
            }

            // find support point on minkowski in the direction of this normal vector
            support = getSupport(prismA, prismB, normal);

            // remove this side from from the list and add the two new sides in the list
            simplex.Remove(closestSide);
            simplex.Add(new Tuple <Vector3, Vector3>(closestSide.Item1, support - closestSide.Item1));
            simplex.Add(new Tuple <Vector3, Vector3>(support, closestSide.Item2));
        }
        // Debug.DrawLine(Vector3.zero, support, Color.yellow,UPDATE_RATE);
        return(support);
    }
예제 #27
0
    // Sets the thickness of the portal screen so as not to clip with camera near plane when player goes through
    void ProtectScreenFromClipping(Vector3 viewPoint)
    {
        float halfHeight = Camera.main.nearClipPlane * Mathf.Tan(Camera.main.fieldOfView * 0.5f * Mathf.Deg2Rad);
        float halfWidth  = halfHeight * Camera.main.aspect;
        float dstToNearClipPlaneCorner = new Vector3(halfWidth, halfHeight, Camera.main.nearClipPlane).magnitude;
        float screenThickness          = dstToNearClipPlaneCorner;

        Transform screenT = screen.transform;
        bool      camFacingSameDirAsPortal = Vector3.Dot(transform.forward, transform.position - viewPoint) > 0;

        screenT.localScale    = new Vector3(screenT.localScale.x, screenT.localScale.y, screenThickness);
        screenT.localPosition = Vector3.forward * screenThickness * (camFacingSameDirAsPortal ? 0.5f : -0.5f);
    }
    public Vector3 PositionUnderMousePlaneAndSphere(out bool fail)
    {
        fail = false;
        Vector3 result         = PositionUnderMousePlane(out fail);
        Vector3 d              = result - atom.molecularParent.transform.position;
        float   targetDistance = atom.distanceToMolecularParent;
        float   dot            = Vector3.Dot(WorldNormal(), d);
        Vector3 dn             = WorldNormal() * dot; //component along plane normal
        Vector3 dp             = d - dn;              //component on plane  (d = dn + dp)
        float   targetDp       = Mathf.Sqrt(Mathf.Abs(targetDistance * targetDistance - dot * dot));

        dp = dp.normalized * targetDp;
        return(atom.molecularParent.transform.position + dp + dn);
    }
예제 #29
0
    void AdjustVelocity()
    {
        float   acceleration, speed;
        Vector3 xAxis, zAxis;

        if (Climbing)
        {
            acceleration = maxClimbAcceleration;
            speed        = maxClimbSpeed;
            xAxis        = Vector3.Cross(contactNormal, upAxis);
            zAxis        = upAxis;
        }
        else if (InWater)
        {
            float swimFactor = Mathf.Min(1f, submergence / swimThreshold);
            acceleration = Mathf.LerpUnclamped(OnGround ? maxAcceleration : maxAirAcceleration,
                                               maxSwimAcceleration, swimFactor);
            speed = Mathf.LerpUnclamped(maxSpeed, maxSwimSpeed, swimFactor);
            xAxis = rightAxis;
            zAxis = forwardAxis;
        }
        else
        {
            acceleration = OnGround ? maxAcceleration : maxAirAcceleration;
            speed        = OnGround && desiresClimbing ? maxClimbSpeed : maxSpeed;
            xAxis        = rightAxis;
            zAxis        = forwardAxis;
        }

        float maxSpeedChange = acceleration * Time.deltaTime;

        xAxis = ProjectOnContactPlane(xAxis, contactNormal);
        zAxis = ProjectOnContactPlane(zAxis, contactNormal);

        Vector3 relativeVelocity = velocity - connectionVelocity;
        float   currentX         = Vector3.Dot(relativeVelocity, xAxis);
        float   currentZ         = Vector3.Dot(relativeVelocity, zAxis);

        float newX = Mathf.MoveTowards(currentX, playerInput.x * speed, maxSpeedChange);
        float newZ = Mathf.MoveTowards(currentZ, playerInput.y * speed, maxSpeedChange);

        velocity += xAxis * (newX - currentX) + zAxis * (newZ - currentZ);

        if (Swimming)
        {
            float currentY = Vector3.Dot(relativeVelocity, upAxis);
            float newY     = Mathf.MoveTowards(currentY, playerInput.z * speed, maxSpeedChange);
            velocity += upAxis * (newY - currentY);
        }
    }
예제 #30
0
파일: AILerp.cs 프로젝트: pinzeweifen/DCET
        /** Finds the closest point on the current path and configures the #interpolator */
        protected virtual void ConfigureNewPath()
        {
            var hadValidPath = interpolator.valid;
            var prevTangent  = hadValidPath ? interpolator.tangent : Vector3.zero;

            interpolator.SetPath(path.vectorPath);
            interpolator.MoveToClosestPoint(GetFeetPosition());

            if (interpolatePathSwitches && switchPathInterpolationSpeed > 0.01f && hadValidPath)
            {
                var correctionFactor = Mathf.Max(-Vector3.Dot(prevTangent.normalized, interpolator.tangent.normalized), 0);
                interpolator.distance -= speed * correctionFactor * (1f / switchPathInterpolationSpeed);
            }
        }