Inheritance: MonoBehaviour
        private Quaternion getAngle(Vector2 p2)
        {
            // var angle = Mathf.Atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Mathf.PI;
            var angle = Math3d.AngleBetweenVector2(AsUp, p2);

            return(Quaternion.AngleAxis(angle, AsForward));
        }
示例#2
0
    void Fall_SuperUpdate()
    {
        if (AcquiringGround())
        {
            moveDirection = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
            currentState  = PlayerStates.Idle;
            return;
        }

        if (input.Current.JumpInput && doubleJump == false)
        {
            currentState = PlayerStates.DoubleJump;
            return;
        }

        if (input.Current.JumpInput && doubleJump == true)
        {
            currentState = PlayerStates.Glide;
            return;
        }

        Vector3 planarMoveDirection   = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
        Vector3 verticalMoveDirection = moveDirection - planarMoveDirection;

        planarMoveDirection     = Vector3.MoveTowards(planarMoveDirection, LocalMovement() * WalkSpeed, JumpAcceleration * controller.deltaTime);
        verticalMoveDirection  -= controller.up * Gravity * controller.deltaTime;
        verticalMoveDirection.y = Mathf.Max(verticalMoveDirection.y, -7f);

        moveDirection = planarMoveDirection + verticalMoveDirection;
    }
    void WallSlide_SuperUpdate()
    {
        if (input.Current.MoveInput == Vector3.zero || Vector3.Dot(collisionVector, LocalMovement()) > 0)
        {
            currentState = PlayerStates.Fall;
            return;
        }

        Vector3 planarMoveDirection   = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
        Vector3 verticalMoveDirection = moveDirection - planarMoveDirection;

        if (Vector3.Angle(verticalMoveDirection, controller.up) > 90 && AcquiringGround())
        {
            moveDirection = planarMoveDirection;
            currentState  = PlayerStates.Idle;
            return;
        }

        if (input.Current.JumpInput)
        {
            moveDirection = collisionVector * 8;
            currentState  = PlayerStates.Jump;
            return;
        }

        moveDirection -= controller.up * Gravity * 0.1f * Time.deltaTime;
    }
示例#4
0
    public void CreateEdgesBetweenNodes()
    {
        foreach (var node in m_graph.Nodes)
        {
            foreach (var dir in Graph.allDirections)
            {
                var nextPos      = new Vector3(node.position.x + dir.x, 0f, node.position.z + dir.y);
                var neighborNode = GetNodeAtPosition(nextPos);

                if (neighborNode != null &&
                    neighborNode.nodeType != NodeType.Blocked &&
                    node.nodeType != NodeType.Blocked)
                {
                    // TODO: this blocked by wall stuff works fine, but i was tired and its quite ugly.
                    bool isBlockedByWall = false;

                    foreach (var wall in walls)
                    {
                        var blocked = Math3d.AreLineSegmentsCrossing(node.position, neighborNode.position, wall.wallPoints[0].position, wall.wallPoints[1].position);
                        if (blocked)
                        {
                            isBlockedByWall = true;
                            break;
                        }
                    }

                    if (!isBlockedByWall)
                    {
                        m_graph.AddEdge(node.NodeIndex, neighborNode.NodeIndex, m_terrainCosts.GetCost(neighborNode.nodeType));
                    }
                }
            }
        }
    }
示例#5
0
    /// <summary>
    /// Method used to calculate destination position when player jumps.
    /// </summary>
    /// <returns>The player's jump destination position.</returns>
    /// <param name="jumpStartPosition">Jump start position (typically, player's current position).</param>
    /// <param name="currentVertexFollowed">Current vertex that is being followed.</param>
    public Vector2 GetJumpDestinationPosition(Vector2 jumpStartPosition, VertexController currentVertexFollowed)
    {
        int currentVertexIndex  = currentVertexFollowed.transform.GetSiblingIndex();
        int previousVertexIndex = currentVertexIndex - 1;

        previousVertexIndex = previousVertexIndex < 0 ? previousVertexIndex + this.transform.childCount : previousVertexIndex;
        VertexController previousVertex = this.transform.GetChild(previousVertexIndex).GetComponent <VertexController>();
        int nextVertexIndex             = (currentVertexIndex + 1) % this.transform.childCount;
        VertexController nextVertex     = this.transform.GetChild(nextVertexIndex).GetComponent <VertexController>();

        Vector2 line = (nextVertex.transform.position - previousVertex.transform.position).normalized;

        line = line.y < 0 ? -line : line;
        float lineA = Mathf.Tan(Vector2.Angle(line, Vector2.right) * Mathf.Deg2Rad);
        float lineB = jumpStartPosition.y - (lineA * jumpStartPosition.x);

        Vector2 linePoint1 = new Vector2(0, lineB);
        Vector2 linePoint2 = new Vector2(1, lineA + lineB);

        // Debug lines drawing, uncomment to debug this method
        //Debug.DrawLine(previousVertex.transform.position, nextVertex.transform.position, Color.green, 3f);
        //Debug.DrawLine(linePoint1, linePoint2, Color.red, 3f);
        //Debug.DrawLine(jumpStartPosition + Vector2.left, jumpStartPosition + Vector2.right, Color.white, 3f);
        //Debug.DrawLine(jumpStartPosition + Vector2.down, jumpStartPosition + Vector2.up, Color.white, 3f);

        Vector3 intersectionPoint = Vector3.zero;

        Math3d.LineLineIntersection(out intersectionPoint, currentVertexFollowed.transform.position, (nextVertex.transform.position - currentVertexFollowed.transform.position).normalized, linePoint1, (linePoint2 - linePoint1).normalized);

        return(intersectionPoint);
    }
示例#6
0
    /// <summary>
    /// Gets proper next folder's position. Used to spawn folders in available positions.
    /// </summary>
    /// <returns>KeyValuePair of vertices used to calculate spawn position and spawn position.</returns>
    /// <param name="currentVertexFollowed">Current vertex followed.</param>
    public KeyValuePair <VertexController[], Vector2> GetNextFolderPosition(VertexController currentVertexFollowed)
    {
        int currentVertexIndex          = currentVertexFollowed.transform.GetSiblingIndex();
        int nextVertexIndex             = (currentVertexIndex + 1) % this.transform.childCount;
        VertexController nextVertex     = this.transform.GetChild(nextVertexIndex).GetComponent <VertexController>();
        int nextNextVertexIndex         = (currentVertexIndex + 2) % this.transform.childCount;
        VertexController nextNextVertex = this.transform.GetChild(nextNextVertexIndex).GetComponent <VertexController>();

        float   availableSpaceScale   = 0.5f;
        Vector2 availableSpaceVertex1 = currentVertexFollowed.transform.position + (nextVertex.transform.position - currentVertexFollowed.transform.position) * (1f - availableSpaceScale) / 3f;

        availableSpaceVertex1 += (Vector2)(nextNextVertex.transform.position - currentVertexFollowed.transform.position) * (1f - availableSpaceScale) / 3f;

        Vector2 availableSpaceVertex2 = nextVertex.transform.position + (currentVertexFollowed.transform.position - nextVertex.transform.position) * (1f - availableSpaceScale) / 3f;

        availableSpaceVertex2 += (Vector2)(nextNextVertex.transform.position - nextVertex.transform.position) * (1f - availableSpaceScale) / 3f;

        Vector2 availableSpaceVertex3 = nextNextVertex.transform.position + (currentVertexFollowed.transform.position - nextNextVertex.transform.position) * (1f - availableSpaceScale) / 3f;

        availableSpaceVertex3 += (Vector2)(nextVertex.transform.position - nextNextVertex.transform.position) * (1f - availableSpaceScale) / 3f;

        // Debug lines drawing, uncomment to debug this method
        //Debug.DrawLine(availableSpaceVertex1, availableSpaceVertex2, Color.white, 3f);
        //Debug.DrawLine(availableSpaceVertex2, availableSpaceVertex3, Color.white, 3f);
        //Debug.DrawLine(availableSpaceVertex3, availableSpaceVertex1, Color.white, 3f);

        VertexController[] returnList = { currentVertexFollowed, nextVertex, nextNextVertex };

        return(new KeyValuePair <VertexController[], Vector2>(returnList, Math3d.GetRandomPointInsideTriangle(availableSpaceVertex1, availableSpaceVertex2, availableSpaceVertex3)));
    }
    /// <summary>
    ///     Provides raycast data based on where a SphereCast would contact the specified normal
    ///     Raycasting downwards from a point along the controller's bottom sphere, based on the provided
    ///     normal
    /// </summary>
    /// <param name="groundNormal">Normal of a triangle assumed to be directly below the controller</param>
    /// <param name="hit">Simulated SphereCast data</param>
    /// <returns>True if the raycast is successful</returns>
    private bool SimulateSphereCast(Vector3 groundNormal, out RaycastHit hit)
    {
        var groundAngle = Vector3.Angle(groundNormal, up) * Mathf.Deg2Rad;

        var secondaryOrigin = transform.position + up * Tolerance;

        if (!Mathf.Approximately(groundAngle, 0))
        {
            var horizontal = Mathf.Sin(groundAngle) * radius;
            var vertical   = (1.0f - Mathf.Cos(groundAngle)) * radius;

            // Retrieve a vector pointing up the slope
            var r2 = Vector3.Cross(groundNormal, down);
            var v2 = -Vector3.Cross(r2, groundNormal);

            secondaryOrigin += Math3d.ProjectVectorOnPlane(up, v2).normalized *horizontal + up * vertical;
        }

        if (Physics.Raycast(secondaryOrigin, down, out hit, Mathf.Infinity, Walkable))
        {
            // Remove the tolerance from the distance travelled
            hit.distance -= Tolerance;

            return(true);
        }
        return(false);
    }
示例#8
0
    // Update is called once per frame
    void Update()
    {
        Vector3 direction = Math3d.ProjectVectorOnPlane(transform.up, (target.position - transform.position).normalized);

        if (Vector3.Distance(target.position, transform.position) < SightDistance && Vector3.Angle(direction, transform.forward) > SightAngle)
        {
            transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(direction), TurnSpeed * Time.deltaTime);

            if (!AnimatedMesh.GetComponent <Animation>().IsPlaying("turn"))
            {
                AnimatedMesh.GetComponent <Animation>().Play("turn");

                GetComponent <AudioSource>().Play();
            }
        }
        else
        {
            if (!AnimatedMesh.GetComponent <Animation>().isPlaying)
            {
                AnimatedMesh.GetComponent <Animation>().Play("idle");
            }
        }

        windRotation = SuperMath.ClampAngle(windRotation + 360.0f * Time.deltaTime);

        WindTransform.Rotation = Quaternion.Euler(new Vector3(0, 0, windRotation));
    }
示例#9
0
 protected override bool Compare(Fact solution, Fact fact)
 {
     return(fact is LineFact && solution is LineFact &&
            Math3d.IsApproximatelyParallel(((LineFact)fact).Dir, ((LineFact)solution).Dir) &&
            ((LineFact)fact).Distance + Math3d.vectorPrecission >= ((LineFact)solution).Distance);
     // && Mathf.Approximately(((LineFact) x).Distance, ((LineFact) y).Distance);
 }
示例#10
0
        public static IPoly RemoveDuplicateVerticies(IPoly poly)
        {
            List <Vector3> output = new List <Vector3>();

            for (int i = 0; i < poly.Resolution; i++)
            {
                if (output.Count == 0)
                {
                    output.Add(poly.GetPoint(i));
                }
                else
                {
                    Vector3 point = poly.GetPoint(i);
                    Vector3 last  = output[output.Count - 1];
                    if (!Math3d.Compare(point, last))
                    {
                        output.Add(point);
                    }
                }
            }
            if (Math3d.Compare(output[0], output[output.Count - 1]))
            {
                output.RemoveAt(0);
            }
            return(poly.Clone(output.ToArray()));
        }
示例#11
0
        public static bool IsEdgeIntersectingPolygon(IPoly polygon, Vector3 point1, Vector3 point2)
        {
            for (int i = 0; i < polygon.Resolution; i++)
            {
                Vector3 a = polygon.GetPoint(i);
                Vector3 b = polygon.GetPointWrapped(i + 1);
                if ((point1 - a).sqrMagnitude < 0.0001f)
                {
                    continue;
                }
                if ((point1 - b).sqrMagnitude < 0.0001f)
                {
                    continue;
                }
                if ((point2 - a).sqrMagnitude < 0.0001f)
                {
                    continue;
                }
                if ((point2 - b).sqrMagnitude < 0.0001f)
                {
                    continue;
                }

                if (Math3d.AreLineSegmentsCrossing(a, b, point1, point2))
                {
                    return(true);
                }
            }
            return(false);
        }
示例#12
0
    private void OnDrawGizmos()
    {
        Vector3 hitPointOnPlane = Math3d.ProjectPointOnPlane(_plane.up, _plane.position
                                                             , transform.position);

        Debug.DrawLine(transform.position, hitPointOnPlane, Color.red);
    }
示例#13
0
        /*
         * Provides raycast data based on where a SphereCast would have contacted
         * the specified normal.
         * Raycasting downwards from a point along the controller's bottom sphere,
         * based on the provided normal.
         */
        private bool SimulateSphereCast(CollisionSphere collisionSphere, Vector3 groundNormal, out RaycastHit hit)
        {
            float groundAngle = Vector3.Angle(groundNormal, playerView.Up) * Mathf.Deg2Rad;

            Vector3 secondaryOrigin = playerView.Position + (playerView.Up * settings.tolerance);

            if (!Mathf.Approximately(groundAngle, 0))
            {
                float horizontal = Mathf.Sin(groundAngle) * collisionSphere.Radius;
                float vertical   = (1f - Mathf.Cos(groundAngle)) * collisionSphere.Radius;

                Vector3 upslopeDirection = -CollisionMath.DownslopeDirection(groundNormal, playerView.Down);

                Vector3 horizontalDirection = Math3d.ProjectVectorOnPlane(playerView.Up, upslopeDirection).normalized;
                secondaryOrigin += horizontalDirection * horizontal + playerView.Up * vertical;
            }

            if (SphereCast(secondaryOrigin, settings.epsilon, playerView.Down, out hit))
            {
                hit.distance -= settings.tolerance;
                return(true);
            }

            return(false);
        }
示例#14
0
    private bool GoldBodySlam()
    {
        float radius = controller.radius * 1.5f;

        Collider[] colliders = Physics.OverlapSphere(transform.position + controller.up * controller.height * 0.5f, radius);

        foreach (var col in colliders)
        {
            EnemyMachine machine = col.GetComponent <EnemyMachine>();

            if (machine != null)
            {
                if (machine.GetStruck(Math3d.ProjectVectorOnPlane(controller.up, machine.transform.position - transform.position).normalized, 7.0f, 15.0f))
                {
                    sound.PlayImpact();

                    machine.MakeGold();
                }
            }

            RollingBallGoldDestroy ball = col.GetComponent <RollingBallGoldDestroy>();

            if (ball)
            {
                ball.BlowUp();
            }
        }

        return(false);
    }
示例#15
0
    /// <summary>
    /// Attempt to get an object out of the dictionary, returning true if the object is in the dictinoary, and false otherwise
    /// The object will be returned to the out parameter t
    /// </summary>
    /// <param name="point"></param>
    /// <param name="direction"></param>
    /// <param name="t"></param>
    /// <returns></returns>
    public bool TryGet(Vector3 point, Vector3 direction, out T t)
    {
        point     = Math3d.LinePlaneIntersection(point, direction, Vector3.zero, direction);
        direction = direction.normalized;
        PointDictionary <T> vectors;

        if (intersections.TryGet(point, out vectors))
        {
            if (vectors.TryGet(direction, out t))
            {
                return(true);
            }
            else if (vectors.TryGet(-direction, out t))
            {
                return(true);
            }
            else
            {
                t = default(T);
                return(false);
            }
        }
        else
        {
            t = default(T);
            return(false);
        }
    }
示例#16
0
    public bool HeavyDamage(int damage, Vector3 origin)
    {
        if (status.Invincible())
        {
            return(false);
        }

        if (StateCompare(MarioStates.Knockback) || StateCompare(MarioStates.KnockbackForwards) || StateCompare(MarioStates.TeleportIn) || StateCompare(MarioStates.TeleportOut))
        {
            return(false);
        }

        Vector3 direction = Math3d.ProjectVectorOnPlane(controller.up, origin - transform.position).normalized;

        if (direction == Vector3.zero)
        {
            direction = lookDirection;
        }

        bool forward = Vector3.Angle(direction, lookDirection) < 90;

        if (Airborn())
        {
            if (forward)
            {
                moveSpeed    = -3.0f;
                currentState = MarioStates.AirKnockback;
            }
            else
            {
                moveSpeed    = 3.0f;
                currentState = MarioStates.AirKnockbackForwards;
            }
        }
        else
        {
            if (forward)
            {
                currentState = MarioStates.Knockback;
                moveSpeed    = -3.0f;
            }
            else
            {
                currentState = MarioStates.KnockbackForwards;
                moveSpeed    = 3.0f;
            }
        }

        lookDirection = forward ? direction : -direction;

        SmartCamera.Shake(1.6f, 25.0f, 0.5f);

        sound.PlayTakeDamage();

        Instantiate(TakeDamageEffect, transform.position + controller.up * controller.height * 0.6f, Quaternion.identity);

        status.TakeDamage(damage);

        return(true);
    }
示例#17
0
    private float WallCollisionAngle(Vector3 wallNormal, Vector3 direction)
    {
        Vector3 planarDirection = Math3d.ProjectVectorOnPlane(controller.up, direction);
        Vector3 planarWall      = Math3d.ProjectVectorOnPlane(controller.up, wallNormal);

        return(Vector3.Angle(planarWall, planarDirection));
    }
示例#18
0
    //Calculates the triangle points (counter clockwise) of a triangle placed over a unit quad.
    //This way a triangle is created which fits over a texture.
    private static void GenerateTriangle(out Vector4[] points, out Vector2[] uvs, float size, Quaternion rotation)
    {
        uvs = new Vector2[3];

        //Calculate the horizontal displacement.
        float x = (1f / Mathf.Tan(60f * Mathf.Deg2Rad)) + 0.5f;

        //Calculate the vertical displacement.
        float y = (0.5f / Mathf.Tan(30f * Mathf.Deg2Rad)) + 0.5f;

        //Set the points, counter clockwise as an upright triangle, with the left
        //corner as point 0, right corner point 1, and top is point 2.
        Vector3[] localPoints = new Vector3[3];
        localPoints[0] = new Vector3(-x, -0.5f) * size;
        localPoints[1] = new Vector3(x, -0.5f) * size;
        localPoints[2] = new Vector3(0, y) * size;

        //Set the uv's
        for (int i = 0; i < 3; i++)
        {
            float u = Math3d.NormalizeComplex(localPoints[i].x / size, -0.5f, 0.5f);
            float v = Math3d.NormalizeComplex(localPoints[i].y / size, -0.5f, 0.5f);
            uvs[i] = new Vector2(u, v);
        }

        //Rotate the points
        for (int i = 0; i < 3; i++)
        {
            localPoints[i] = rotation * localPoints[i];
        }

        //Convert to vector4
        points = Vector3ToVector4(localPoints);
    }
        /// <summary>
        /// Provides raycast data based on where a SphereCast would contact the specified normal
        /// Raycasting downwards from a point along the controller's bottom sphere, based on the provided
        /// normal
        /// </summary>
        /// <param name="groundNormal">Normal of a triangle assumed to be directly below the controller</param>
        /// <param name="hit">Simulated SphereCast data</param>
        /// <returns>True if the raycast is successful</returns>
        private bool SimulateSphereCast(Vector3 groundNormal, out RaycastHit hit)
        {
            float groundAngle = Vector3.Angle(groundNormal, controller.up) * Mathf.Deg2Rad;

            Vector3 secondaryOrigin = controller.transform.position + controller.up * Tolerance;

            if (!Mathf.Approximately(groundAngle, 0))
            {
                float horizontal = Mathf.Sin(groundAngle) * controller.radius;
                float vertical   = (1.0f - Mathf.Cos(groundAngle)) * controller.radius;

                // Retrieve a vector pointing up the slope
                Vector3 r2 = Vector3.Cross(groundNormal, controller.down);
                Vector3 v2 = -Vector3.Cross(r2, groundNormal);

                secondaryOrigin += Math3d.ProjectVectorOnPlane(controller.up, v2).normalized *horizontal + controller.up * vertical;
            }

            if (Physics.Raycast(secondaryOrigin, controller.down, out hit, Mathf.Infinity, walkable, triggerInteraction))
            {
                // Remove the tolerance from the distance travelled
                hit.distance -= Tolerance + TinyTolerance;

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#20
0
        public static Vector3 Circumcenter(Vector3 pt1, Vector3 pt2, Vector3 pt3)
        {
            // Get the perpendicular bisector of pt1, pt2
            Vector3 v12           = pt2 - pt1;
            Vector3 v12normalized = v12.normalized;
            Vector3 v13           = pt3 - pt1;
            Vector3 v13normalized = v13.normalized;

            Vector3 v12perp = v13 - (Vector3.Dot(v13, v12normalized)) * v12normalized;

            v12perp.Normalize();

            // Get the perpendicular bisector of pt1, pt3
            Vector3 v13perp = v12 - (Vector3.Dot(v12, v13normalized)) * v13normalized;

            v13perp.Normalize();

            Vector3 v12base = (pt1 + pt2) / 2;
            Vector3 v13base = (pt1 + pt3) / 2;

            // Compute intersection of the two bisectors
            Vector3 closest1, closest2;

            Math3d.ClosestPointsOnTwoLines(out closest1, out closest2, v12base, v12perp, v13base, v13perp);

            return((closest1 + closest2) / 2);
        }
示例#21
0
    // Update is called once per frame
    void FixedUpdate()
    {
        if (_isShoot)                                           // neu da sut roi`
        {
            if (_ballRigidBody.velocity.sqrMagnitude <= 0.001f) // banh dung yen, ko can tinh' diem~ giao cat'
            {
                _ballTarget.position = Vector3.zero;
            }
            else
            {
                Vector3 intersection = Vector3.zero;
                if (Math3d.LinePlaneIntersection(out intersection, _ballRigidBody.position, (_ballRigidBody.velocity).normalized, _endPoint.up, _endPoint.position))                    // tim giao diem giua~ mat phang gan` thu mon va duong di cua trai banh,
                {
                    intersection.y       = Mathf.Clamp(intersection.y, 0, 3f);
                    intersection.x       = Mathf.Clamp(intersection.x, -5f, 5f);
                    _ballTarget.position = intersection;                                //  set vi tri ballTarget la vi tri giao diem tim duoc
                }
                else
                {
                    // ball target la diem~ co' x,y = x,y cua ball. z = z cua _endpoint, xem endpoint nhu mat phang~ gan thu~ mon,
                    // thu mon se~ bay nguoi can fa' khi banh giao cat' voi' mat phang~ nay`, va _ballTarget chinh' la diem~ giao cat'
                    // giua~ duong` di cua~ ball va mat phang~ nay

                    Vector3 posTemp = _ball.position;
                    posTemp.z            = _endPoint.position.z;
                    _ballTarget.position = posTemp;
                }
            }
            _previousPos = _ballRigidBody.position;
            _ballTargetPrevious.position = _previousPos;
        }
        else
        {
        }
    }
示例#22
0
    public void OnTrackablesUpdated()
    {
        if (rotations.Count >= smoothingFrames)
        {
            rotations.Dequeue();
            positions.Dequeue();
        }

        rotations.Enqueue(transform.rotation);
        positions.Enqueue(transform.position);

        Vector4 avgr = Vector4.zero;

        foreach (Quaternion singleRotation in rotations)
        {
            Math3d.AverageQuaternion(ref avgr, singleRotation, rotations.Peek(), rotations.Count);
        }

        Vector3 avgp = Vector3.zero;

        foreach (Vector3 singlePosition in positions)
        {
            avgp += singlePosition;
        }
        avgp /= positions.Count;

        smoothedRotation = new Quaternion(avgr.x, avgr.y, avgr.z, avgr.w);
        smoothedPosition = avgp;
    }
示例#23
0
        /// <summary>
        /// Splits the vertices and normals of each triangle in the mesh so that none are shared by any two triangles.
        /// </summary>
        /// <remarks>This achieves a flat-shaded lighting effect on the mesh.</remarks>
        /// <param name="mesh">Mesh.</param>
        public static void SplitVertices(this Mesh mesh)
        {
            var triangles = mesh.triangles;
            var vertices  = mesh.vertices;
            var newVerts  = new Vector3[triangles.Length];
            var newNorms  = new Vector3[triangles.Length];

            for (int i = 0; i < triangles.Length; i++)
            {
                newVerts[i]  = vertices[triangles[i]];
                triangles[i] = i;
            }

            for (int i = 0; i < triangles.Length; i += 3)
            {
                Vector3 normal, point;
                Math3d.PlaneFrom3Points(out normal, out point, newVerts[triangles[i]], newVerts[triangles[i + 1]], newVerts[triangles[i + 2]]);

                newNorms[i]     = normal;
                newNorms[i + 1] = normal;
                newNorms[i + 2] = normal;
            }

            mesh.vertices  = newVerts;
            mesh.triangles = triangles;
            mesh.normals   = newNorms;
        }
示例#24
0
        /// <summary>
        /// Expands a polygon by the specified distance.
        /// </summary>
        /// <param name="poly"></param>
        /// <param name="distance"></param>
        /// <param name="constructor"></param>
        /// <returns></returns>
        public static IPoly Expand(this IPoly poly, float distance, Func <IEnumerable <Vector3>, IPoly> constructor = null)
        {
            if (constructor == null)
            {
                constructor = poly.Clone;
            }
            Vector3[] points    = new Vector3[poly.Resolution];
            Vector3[] normals   = new Vector3[poly.Resolution];
            Vector3[] direction = new Vector3[poly.Resolution];
            for (int i = 0; i < poly.Resolution; i++)
            {
                points[i]    = poly.GetPoint(i);
                normals[i]   = poly.GetSurfaceNormal(i).normalized;
                direction[i] = poly.GetPoint((i + 1) % poly.Resolution) - poly.GetPoint(i);
            }

            Vector3[] outputPoints = new Vector3[poly.Resolution];
            for (int i = 0; i < poly.Resolution; i++)
            {
                Vector3 p0     = points[i] + normals[i] * distance;
                int     iMinus = (i - 1 + poly.Resolution) % poly.Resolution;
                Vector3 l0     = points[iMinus] + normals[iMinus] * distance;
                outputPoints[i] = Math3d.LinePlaneIntersection(l0, direction[iMinus], p0, normals[i]);
            }

            return(constructor(outputPoints));
        }
    void Wander_SuperUpdate()
    {
        if (!IsGrounded(0.5f, true))
        {
            currentState = BobOmbStates.Fall;
            return;
        }

        Vector3 direction = target.position - transform.position;

        direction = Math3d.ProjectVectorOnPlane(controller.up, direction);

        float distance = Vector3.Distance(target.position, transform.position);

        if (Vector3.Angle(direction, lookDirection) < FieldOfView && distance < SightDistance)
        {
            currentState = BobOmbStates.Chase;
            return;
        }

        moveSpeed = Mathf.MoveTowards(moveSpeed, WanderSpeed, 3.0f * Time.deltaTime);

        lookDirection = Quaternion.AngleAxis(30.0f * Time.deltaTime, controller.up) * lookDirection;

        moveDirection = moveSpeed * lookDirection;
    }
示例#26
0
    //Get an average (mean) from more then two quaternions (with two, slerp would be used).
    //Note: this only works if all the quaternions are relatively close together.
    //Usage:
    //-Cumulative is an external Vector4 which holds all the added x y z and w components.
    //-newRotation is the next rotation to be added to the average pool
    //-firstRotation is the first quaternion of the array to be averaged
    //-addAmount holds the total amount of quaternions which are currently added
    //This function returns the current average quaternion
    public static void AverageQuaternion(ref Vector4 cumulative, Quaternion newRotation, Quaternion firstRotation, int addAmount)
    {
        float w = 0.0f;
        float x = 0.0f;
        float y = 0.0f;
        float z = 0.0f;

        //Before we add the new rotation to the average (mean), we have to check whether the quaternion has to be inverted. Because
        //q and -q are the same rotation, but cannot be averaged, we have to make sure they are all the same.
        if (!Math3d.AreQuaternionsClose(newRotation, firstRotation))
        {
            newRotation = Math3d.InverseSignQuaternion(newRotation);
        }

        //Average the values
        float addDet = 1f / (float)addAmount;

        cumulative.w += newRotation.w;
        w             = cumulative.w * addDet;
        cumulative.x += newRotation.x;
        x             = cumulative.x * addDet;
        cumulative.y += newRotation.y;
        y             = cumulative.y * addDet;
        cumulative.z += newRotation.z;
        z             = cumulative.z * addDet;

        //note: if speed is an issue, you can skip the normalization step
        //return NormalizeQuaternion(x, y, z, w);
    }
示例#27
0
    bool SlopeLimit()
    {
        //Calculate the angle with the current ground first to see if it is greater than slope limit
        Vector3 n = _currentGround.normal;
        float   a = Vector3.Angle(n, transform.up);

        if (a > slopeLimit)
        {
            //Grab the direction that the controller is moving in
            Vector3 absoluteMoveDirection = Math3d.ProjectVectorOnPlane(n, transform.position - initialPosition);

            // Retrieve a vector pointing down the slope
            Vector3 r = Vector3.Cross(n, -transform.up);
            Vector3 v = Vector3.Cross(r, n);

            //Check the angle between the move direction of the controller and a vector down the slope. If less than 90 degrees then the player is moving down the slope return false
            float angle = Vector3.Angle(absoluteMoveDirection, v);

            if (angle <= 90.0f)
            {
                return(false);
            }

            // Calculate where to place the controller on the slope, or at the bottom, based on the desired movement distance
            Vector3 resolvedPosition = Math3d.ProjectPointOnLine(initialPosition, r, transform.position);
            Vector3 direction        = Math3d.ProjectVectorOnPlane(n, resolvedPosition - transform.position);

            transform.position += direction;

            return(true);
        }

        return(false);
    }
示例#28
0
    public void SetTargetWithAngle(Vector3 point, float angle)
    {
        currentRadian = angle * Mathf.Deg2Rad;

        targetPoint = point;
        //GizmosHelper.DrawBox(point, Vector3.one * 0.2f, Color.yellow);
        Vector3 direction = point - firePoint.position;

        //if (Vector3.Angle(direction, transform.forward) > 10)
        //{
        //    // Haven't face the right direction.
        //    projectileArc.gameObject.SetActive(false);
        //    return;
        //}
        //else
        //{
        //    projectileArc.gameObject.SetActive(true);
        //}

        float yOffset = direction.y;

        direction = Math3d.ProjectVectorOnPlane(Vector3.up, direction);
        float distance = direction.magnitude;

        currentSpeed = ProjectileMath.CalculateLaunchSpeed(distance, yOffset, Physics.gravity.magnitude, angle * Mathf.Deg2Rad);

        projectileArc.UpdateArc(currentSpeed, distance, Physics.gravity.magnitude, currentRadian, direction, true);
        SetThrowPoint(direction, currentRadian * Mathf.Rad2Deg);
    }
示例#29
0
    //Setup all the papi lights.
    private void SetupPapiLights(ref List <SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness)
    {
        for (int side = 0; side < 2; side++)
        {
            if (runwayData.papiType[side] != PapiType.NONE)
            {
                //Calculate the offset direction.
                Vector3 lengthOffsetDir     = Math3d.GetForwardVector(runwayData.rotation[side]);
                Vector3 sideOffsetDir       = Math3d.GetRightVector(runwayData.rotation[side]);
                Vector3 lengthEdgeOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, 337f);

                if ((runwayData.papiType[side] == PapiType.PAPIRIGHT) || (runwayData.papiType[side] == PapiType.PAPIBOTH))
                {
                    Vector3 startOffsetVec  = lengthEdgeOffsetVec + Math3d.SetVectorLength(sideOffsetDir, (runwayData.width * 0.5f) + 15f);
                    Vector3 startPosition   = runwayData.thresholdPosition[side] + startOffsetVec;
                    Vector3 currentPosition = startPosition;

                    Vector3 sideOffsetVec = Math3d.SetVectorLength(sideOffsetDir, 9f);

                    for (int i = 0; i < 4; i++)
                    {
                        SpriteLights.LightData data = new SpriteLights.LightData();

                        float angle = GetPapiAngle(i);

                        data.position = currentPosition;
                        data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * angle);
                        lightData.Add(data);

                        currentPosition += sideOffsetVec;
                    }
                }

                if ((runwayData.papiType[side] == PapiType.PAPILEFT) || (runwayData.papiType[side] == PapiType.PAPIBOTH))
                {
                    sideOffsetDir *= -1;

                    Vector3 startOffsetVec  = lengthEdgeOffsetVec + Math3d.SetVectorLength(sideOffsetDir, (runwayData.width * 0.5f) + 15f);
                    Vector3 startPosition   = runwayData.thresholdPosition[side] + startOffsetVec;
                    Vector3 currentPosition = startPosition;

                    Vector3 sideOffsetVec = Math3d.SetVectorLength(sideOffsetDir, 9f);

                    for (int i = 0; i < 4; i++)
                    {
                        SpriteLights.LightData data = new SpriteLights.LightData();

                        float angle = GetPapiAngle(i);

                        data.position = currentPosition;
                        data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * angle);
                        lightData.Add(data);

                        currentPosition += sideOffsetVec;
                    }
                }
            }
        }
    }
示例#30
0
 static public void LookAt(Transform item, Vector3 target_pos)
 {
     item.localEulerAngles = new Vector3(
         item.localEulerAngles.x,
         item.localEulerAngles.y,
         Math3d.AngleFromUp(target_pos - item.position)
         );
 }