Пример #1
0
        public static Vector3 operator *(Quaternion xform, Vector3 vec)
        {
            /* From nVidia SDK */
            Vector3 uv, uuv;
            Vector3 qvec = new Vector3(xform.X, xform.Y, xform.Z);

            uv = qvec.Cross(vec);
            uuv = qvec.Cross(uv);
            uv *= (2.0f * xform.W);
            uuv *= 2.0f;

            return vec + uv + uuv;
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Quaternion"/> class.
        /// </summary>
        /// <param name="sourcePosition">The source position.</param>
        /// <param name="destinationPosition">The destination position.</param>
        public Quaternion(Vector3 sourcePosition, Vector3 destinationPosition)
        {
            var r = sourcePosition.Cross(destinationPosition);
            var s = Functions.Sqrt(2 * (1 + sourcePosition.Dot(destinationPosition)));

            mValues = new Vector4(r / s, s / 2);
        }
Пример #3
0
        public void Cross()
        {
            var vector1 = new Vector3(2.0f, 3.0f, 4.0f);
            var vector2 = new Vector3(5.0f, 6.0f, 7.0f);

            var cross = vector1.Cross(vector2);
            Assert.AreEqual(-3.0f, cross.X);
            Assert.AreEqual(6.0f, cross.Y);
            Assert.AreEqual(-3.0f, cross.Z);
        }
Пример #4
0
        /// <summary>
        /// 2つのベクトルがなす角をかえす
        /// </summary>
        /// <param name="vecA"></param>
        /// <param name="vecB"></param>
        /// <returns></returns>
        public static double VecToRad( Vector3 vecA, Vector3 vecB )
        {
            vecA.Normalize();
            vecB.Normalize();

            double dir = (double)(Axiom.Math.Utility.ASin(vecA.Dot(vecB)) - Axiom.Math.Utility.HALF_PI);
            Vector3 resVec = vecA.Cross(vecB);
            if (resVec.z < 0) dir = -dir;

            return dir;
        }
Пример #5
0
        public MeshTriangle(byte id, Vector3 p0, Vector3 p1, Vector3 p2)
        {
            Id = id;
            P0 = p0;
            P1 = p1;
            P2 = p2;

            Points = new List<Vector3>{P0, P1, P2};
            U = P1 - P0;
            V = P2 - P0;
            Normal = U.Cross(V).NormalizeRet();

            Direction = CalculateDirection();
            UU = U.Dot(U);
            VV = V.Dot(V);
            UV = U.Dot(V);

            D = UV * UV - UU * VV;
        }
Пример #6
0
    public void ProjectionMesh(Transform meshTransform, Mesh mesh, Ray ray, float radius, Material material)
    {
        //Debug Code Start
        float startTime = Time.realtimeSinceStartup;

        //Debug Code Stop
        Vector3[] meshVertices = mesh.vertices;
        int       newVertices  = 0;

        int[] newTriangles = new int[meshVertices.Length];
        for (int i = 0, j = 0; i < meshVertices.Length; i += 3)
        {
            Vector3 v0 = meshTransform.TransformPoint(meshVertices[i]);
            Vector3 v1 = meshTransform.TransformPoint(meshVertices[i + 1]);
            Vector3 v2 = meshTransform.TransformPoint(meshVertices[i + 2]);
            if (RayTriangleIntersection(ray, v0, v1, v2, radius))
            {
                newTriangles[j]     = i;
                newTriangles[j + 1] = i + 1;
                newTriangles[j + 2] = i + 2;
                j += 3;
            }
            newVertices = j;
        }
        Vector3[] vertices  = new Vector3[newVertices];
        Vector2[] uv        = new Vector2[newVertices];
        int[]     triangles = new int[newVertices];
        Vector3   x         = Vector3.Cross(ray.direction, meshVertices[0]).normalized;
        Vector3   y         = Vector3.Cross(ray.direction, x).normalized;
        Vector2   offset    = new Vector2(Vector3.Dot(ray.origin, -x), Vector3.Dot(ray.origin, -y)) * 0.5f / radius + Vector2.one * 0.5f;

        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i] = meshVertices[newTriangles[i]];
            Vector3 v = meshTransform.TransformPoint(vertices[i]);
            uv[i]        = new Vector2(Vector3.Dot(v, x), Vector3.Dot(v, y)) * 0.5f / radius + offset;
            triangles[i] = i;
        }
        Mesh newMesh = new Mesh();

        newMesh.Clear();
        newMesh.vertices  = vertices;
        newMesh.uv        = uv;
        newMesh.normals   = new Vector3[triangles.Length];
        newMesh.triangles = triangles;
        newMesh.RecalculateNormals();
        GameObject newGameObject = new GameObject();

        newGameObject.AddComponent <MeshFilter>();
        newGameObject.AddComponent <MeshRenderer>();
        newGameObject.GetComponent <MeshFilter>().mesh       = newMesh;
        newGameObject.GetComponent <MeshRenderer>().material = material;
        newGameObject.transform.name          = material.name + " Projection";
        newGameObject.transform.parent        = meshTransform;
        newGameObject.transform.localPosition = Vector3.zero;
        newGameObject.transform.localRotation = Quaternion.identity;
        newGameObject.transform.localScale    = Vector3.one;
        //Debug Code Start
        print("ProjectionMesh total execution time: " + (Time.realtimeSinceStartup - startTime) + " seconds for " + (newMesh.triangles.Length / 3) + " triangles");
        //Debug Code Stop
    }
Пример #7
0
 /// <summary>
 /// Returns the closest distance to the given ray from a point.
 /// </summary>
 /// <param name="ray">The ray.</param>
 /// <param name="point">The point to check distance from the ray.</param>
 /// <returns>Squared distance from the point to the closest point of the ray.</returns>
 public static float SqrDistanceToRay(Ray ray, Vector3 point)
 {
     return(Vector3.Cross(ray.direction, point - ray.origin).sqrMagnitude);
 }
Пример #8
0
        public static Matrix3 LookAt(Vector3 forward, Vector3 up)
        {
            var Z = forward.Normalize();
            var X = up.Cross(Z).Normalize();
            var Y = Z.Cross(X);

            return new Matrix3(X, Y, Z);
        }
Пример #9
0
    void ForceFling()
    {
        Transform flinger;
        Rigidbody flung;
        Vector3   dir;

        Transform activeLink;

        if (partnerNum == 0)
        {
            flinger = partnerRB[0].transform;
            flung   = partnerRB[1];
            vibrationJoystick.Rumble(1, 1f, 0.2f);
            activeLink = links[10];
        }
        else
        {
            partnerNum = 1;
            flinger    = partnerRB[1].transform;
            flung      = partnerRB[0];
            vibrationJoystick.Rumble(0, 1f, 0.2f);
            activeLink = links[2];
        }

        /* ============ New way of handling direction ============ */

        //if (useNewFlingDirection)
        //{
        Vector3 a = flinger.position - flung.position;           // flung -> flinger
        Vector3 b = midLink.transform.position - flung.position; // flung -> midlink

        Debug.DrawRay(flung.position, a, Color.green, 1f);
        Debug.DrawRay(flung.position, b, Color.red, 1f);

        // Rotation axis
        Vector3 axis = Vector3.Cross(a, b).normalized;

        // Direction of fling
        float angle = Vector3.Angle(a, b);

        // If the angle is too small, increase it
        if (angle < 20f)
        {
            angle = flingDirectionAngleCurve.Evaluate(angle);
        }

        dir = b;
        Quaternion rot = Quaternion.AngleAxis(angle, axis);

        dir = (rot * dir).normalized;

        Debug.DrawRay(flung.position, dir * 4f, Color.magenta, 1f, false);
        //}
        //else
        //{
        //    // ============ Old way of handling direction ============ */
        //    if (activeLink.position.y > (flung.transform.position.y + 0.15f) && partnerDistance > ropeLength)
        //        dir = ((activeLink.position - flung.transform.position).normalized + Vector3.up).normalized;

        //    //otherwise, set the direction to be the direction between the two players
        //    else
        //        dir = (activeLink.position - flung.transform.position).normalized;
        //}


        float distance = Vector3.Distance(links[6].transform.position, flung.transform.position);


        float forceMagnitude = tugCurve.Evaluate(distance);

        forceMagnitude *= flingModifier;

        if (forceMagnitude > 650f)
        {
            OnPerfectFlingVisualsAndSound(1 - partnerNum);
            if (!PhotonNetwork.OfflineMode)
            {
                photonView.RPC("OnPerfectFlingVisualsAndSound", RpcTarget.Others, 1 - partnerNum);
            }
        }


        //float forceMagnitude = 8f * pullConstant * distance;
        //Clamp the force so it's magnitude never exceeds a maximum force,
        //which is determined by the maximum length that the rope can be stretched
        //forceMagnitude = Mathf.Clamp(forceMagnitude, 0f, 4f * 6f * pullConstant);

        forceToBeApplied = dir * forceMagnitude;

        //if (forceMagnitude>500f)
        StartCoroutine(PlayFlingTrail(1 - partnerNum, forceMagnitude));
        if (!PhotonNetwork.OfflineMode)
        {
            photonView.RPC("PlayFlingTrailRPC", RpcTarget.Others, 1 - partnerNum, forceMagnitude);
        }

        ApplyTugArrow(flung.transform, dir, forceMagnitude);
        FlingPlayerRB(1 - partnerNum, forceToBeApplied);

        /*if (PhotonNetwork.OfflineMode || flung.GetComponent<PhotonView>().IsMine) {
         *  flung.AddForce(forceToBeApplied, ForceMode.Acceleration);
         * }
         * else {
         *  FlingPlayerRigidbody(partnerNum, forceToBeApplied);
         *  flung.AddForce(forceToBeApplied, ForceMode.Acceleration);
         * }*/

        //Debug.LogWarning("Distance: " + distance + ", Force: " + forceMagnitude);

        //Debug.Log("New Link Based Tug Force: " + forceMagnitude);
        //Debug.Log(currLength);
        //Debug.DrawRay(partner.transform.position, dir, Color.cyan, 0.3f);
    }
Пример #10
0
        /// <summary>
        /// Concatenates two quaternions. The right argument is applied first.
        /// </summary>
        /// <param name="left">The left operand which is applied after the right one.</param>
        /// <param name="right">The right operand which is applied first.</param>
        /// <returns>A quaternion containing the rotations of both given quaternions.</returns>
        public static Quaternion operator *(Quaternion left, Quaternion right)
        {
            var v1 = new Vector3(right.X, right.Y, right.Z);
            var v2 = new Vector3(left.X, left.Y, left.Z);

            var w = left.W * right.W - v1.Dot(v2);
            var v = right.W * v2 + left.W * v1 + v2.Cross(v1);

            return new Quaternion(v, w);
        }
Пример #11
0
    // HANDLING TOUCH INPUT HERE
    void LateUpdate()
    {
        if (overUI && !controlsInUse)
        {
            return;
        }

        var canvasScale = app.scaleFactorRefCanvas.scaleFactor;

                #if UNITY_EDITOR
        // test on iPhone 5c
        //canvasScale = 1.893333f;
                #endif

        //Debug.LogWarning("CANVAS SCALE: "+canvasScale);

        var mltpl = Time.deltaTime * 35f / canvasScale;

        if (hasTouches())
        {
            stopFlying();

            Vector2 touch1Pos = getTouchPos();
            if (touchCount() == 1 && !Input.GetKey(KeyCode.LeftCommand))
            {
                // moving
                firstTouchInRotateMode = true;


                if (firstTouchInMoveMode)
                {
                    Ray        ray = Camera.main.ScreenPointToRay(touch1Pos);
                    RaycastHit hit;
                    int        buildingLayer = 1 << 9 | 1 << 10 | 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14;
                    if (Physics.Raycast(ray.origin, ray.direction, out hit, Mathf.Infinity, buildingLayer))
                    {
                        worldInteractPoint   = hit.point;
                        firstTouchInMoveMode = false;
                        touch1StartPos       = touch1Pos;
                    }
                }
                else
                {
                    var touchDelta = touch1Pos - touch1StartPos;

                    if (touchDelta.magnitude > 0.5f)
                    {
                        controlsInUse = true;
                    }

                    var camToPointDist = (Camera.main.transform.position - worldInteractPoint).magnitude;
                    var h1             = 1f;        //Camera.main.nearClipPlane;
                    var h2             = camToPointDist - h1;

                    var worldDelta             = touchDelta / h1 * h2;
                    var cameraForwardDirection = (Camera.main.transform.forward - new Vector3(0, Camera.main.transform.forward.y, 0)).normalized;
                    var cameraRightDirection   = (Camera.main.transform.right - new Vector3(0, Camera.main.transform.right.y, 0)).normalized;

                    if (canMove)
                    {
                        Camera.main.transform.position -= (cameraForwardDirection * worldDelta.y * mltpl * moveSpeed
                                                           + cameraRightDirection * worldDelta.x * mltpl * moveSpeed);
                    }

                    touch1StartPos = touch1Pos;
                }
            }
            else if (touchCount() == 2 || !touchInput() && Input.GetKey(KeyCode.LeftCommand))
            {
                // rotating
                firstTouchInMoveMode = true;


                if (firstTouchInRotateMode)
                {
                    touch1StartPos = touch1Pos;

                    if (touchInput())
                    {
                        touch2StartPos = getTouch2Pos();
                    }

                    var        startCenterPoint = (touch1StartPos + touch2StartPos) / 2f;
                    Ray        ray = Camera.main.ScreenPointToRay(startCenterPoint);
                    RaycastHit hit;
                    int        buildingLayer = 1 << 9 | 1 << 10 | 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14;
                    if (Physics.Raycast(ray.origin, ray.direction, out hit, Mathf.Infinity, buildingLayer))
                    {
                        worldInteractPoint     = hit.point;
                        firstTouchInRotateMode = false;
                    }
                }
                else
                {
                    if (touchInput())
                    {
                        // rotate and zoom camera with 2 fingers
                        Vector2 touch2Pos          = getTouch2Pos();
                        var     deltaDistance      = (touch2Pos - touch1Pos).magnitude - (touch2StartPos - touch1StartPos).magnitude;
                        var     startCenterPoint   = (touch1StartPos + touch2StartPos) / 2f;
                        var     startVector        = touch1StartPos - touch2StartPos;
                        var     currentCenterPoint = (touch1Pos + touch2Pos) / 2f;
                        var     currentVector      = touch1Pos - touch2Pos;

                        // get signed vector
                        var deltaDegrees = Vector2.Angle(currentVector, startVector);
                        if (Mathf.Abs(deltaDegrees) > 1f)
                        {
                            controlsInUse = true;
                        }

                        Vector3 cross = Vector3.Cross(currentVector, startVector);
                        if (cross.z > 0)
                        {
                            deltaDegrees *= -1;
                        }

                        var deltaY = currentCenterPoint.y - startCenterPoint.y;

                        if (touchRotatePhiZoomMode || touchRotateThetaMode || touchRotatePhiZoomMode)
                        {
                            if (touchRotateThetaMode)
                            {
                                var deltaTheta = deltaY * rotateThetaSpeed * mltpl;
                                Camera.main.transform.RotateAround(worldInteractPoint, Camera.main.transform.right, deltaTheta);
                            }
                            else if (touchRotatePhiZoomMode)
                            {
                                var deltaPhi = deltaDegrees * rotatePhiSpeed /**mltpl*/;
                                var oldPos   = Camera.main.transform.position;
                                Camera.main.transform.RotateAround(worldInteractPoint, Vector3.up, deltaPhi);
                                var heightCoeff = (Camera.main.transform.position.y - minHeight) / (maxHeight - minHeight);
                                if (heightCoeff < 0.1f)
                                {
                                    heightCoeff = 0.1f;
                                }
                                var deltaZoom   = deltaDistance * zoomSpeed * mltpl * heightCoeff;
                                var translation = (worldInteractPoint - Camera.main.transform.position).normalized * deltaZoom;

                                Camera.main.transform.Translate(translation, Space.World);

                                // check if camera too close to worldInteractPoint, and revert changes if too close
                                var pos_after_translate   = Camera.main.transform.position;
                                var dst_to_interact_point = (worldInteractPoint - pos_after_translate).magnitude;
                                //Debug.LogWarning ("DST to interact point: "+dst_to_interact_point);

                                if (dst_to_interact_point < 3f)
                                {
                                    Camera.main.transform.position = oldCamPos;
                                    Camera.main.transform.rotation = oldCamRot;
                                }
                            }
                            else
                            {
                            }
                        }
                        else
                        {
                            if (Mathf.Abs(deltaY) > touchRotateThetaThreshold)
                            {
                                touchRotateThetaMode = true;
                            }
                            else if (Mathf.Abs(deltaDegrees) > touchRotatePhiThreshold ||
                                     Mathf.Abs(deltaDistance) > touchZoomThreshold)
                            {
                                touchRotatePhiZoomMode = true;
                            }
                            else
                            {
                            }
                        }
                        touch1StartPos = touch1Pos;
                        touch2StartPos = touch2Pos;
                    }
                }
            }
        }
        else
        {
            controlsInUse        = false;
            firstTouchInMoveMode = true;

            firstTouchInRotateMode = true;
            touchRotatePhiZoomMode = false;
            touchRotateThetaMode   = false;
        }


        // check camera borders
        var newPos = Camera.main.transform.position;
        var newRot = Camera.main.transform.rotation.eulerAngles;

        var thetaAngle = AngleSigned(Camera.main.transform.up, Vector3.up, -Camera.main.transform.right);



        // borders
        if (!flying)
        {
            if (newPos.y < minHeight || newPos.y > maxHeight ||
                thetaAngle < minAngle || thetaAngle > maxAngle)
            {
                Camera.main.transform.position = oldCamPos;
                Camera.main.transform.rotation = oldCamRot;
            }
            else
            {
                oldCamPos = Camera.main.transform.position;
                oldCamRot = Camera.main.transform.rotation;
            }
        }
    }
Пример #12
0
        public static Matrix LookAtRH(Vector3 eye, Vector3 at, Vector3 up)
        {
            var result = new Matrix();

            Vector3 vectorNormal = (at - eye).Normal;
            Vector3 right = up.Cross(vectorNormal);
            Vector3 rightNormal = right.Normal;
            Vector3 upNormal = vectorNormal.Cross(right).Normal;

            result[0, 0] = -rightNormal.X;
            result[1, 0] = -rightNormal.Y;
            result[2, 0] = -rightNormal.Z;
            result[3, 0] = rightNormal.Dot(eye);
            result[0, 1] = upNormal.X;
            result[1, 1] = upNormal.Y;
            result[2, 1] = upNormal.Z;
            result[3, 1] = -upNormal.Dot(eye);
            result[0, 2] = -vectorNormal.X;
            result[1, 2] = -vectorNormal.Y;
            result[2, 2] = -vectorNormal.Z;
            result[3, 2] = vectorNormal.Dot(eye);
            result[0, 3] = 0.0f;
            result[1, 3] = 0.0f;
            result[2, 3] = 0.0f;
            result[3, 3] = 1.0f;

            return result;
        }
Пример #13
0
    public void Render(Vector3[] points, Vector3[] directions, bool circle)
    {
        int stepsAmount = 0;

        Line[] lines = new Line[circle ? points.Length : points.Length - 1];
        for (int i = 0; i < lines.Length; i++)
        {
            int i2 = (i + 1) % points.Length;
            lines[i] = new Line(new Vector2(points[i].x, points[i].z), new Vector2(points[i2].x, points[i2].z));
        }

        List <Vector3> vertices  = new List <Vector3>();
        List <Vector2> uvs       = new List <Vector2>();
        List <int>     triangles = new List <int>();

        float angle = 0f;

        if (points.Length >= 4)
        {
            for (int i = 0; i < points.Length; i++)
            {
                Vector3 toRight;
                if (circle)
                {
                    Vector3 nextPoint = points[(i + 1) % points.Length];
                    Vector3 prevPoint = points[i - 1 < 0 ? points.Length - 1 : i - 1];

                    toRight = (nextPoint - prevPoint).normalized;

                    angle = 0f;// Vector3.Angle(points[i] - prevPoint, nextPoint - points[i]);

                    for (int j = -2; j <= 2; j++)
                    {
                        int prevJ = (j + i - 1) < 0 ? (points.Length + (j + i - 1)) : ((j + i - 1) % points.Length);
                        int nextJ = (j + i + 1) < 0 ? (points.Length + (j + i + 1)) : ((j + i + 1) % points.Length);
                        int atJ   = (j + i) < 0 ? (points.Length + (j + i)) : ((j + i) % points.Length);

                        float angleHere = Vector3.Angle(points[atJ] - points[prevJ], points[nextJ] - points[atJ]);

                        float factor = 0f;
                        if (Mathf.Abs(j) == 2)
                        {
                            factor = 0.06f;
                        }
                        else if (Mathf.Abs(j) == 1)
                        {
                            factor = 0.23f;
                        }
                        else
                        {
                            factor = 0.42f;
                        }

                        angle += (angleHere * factor);
                    }

                    Vector2 forward = new Vector2(points[i].x - prevPoint.x, points[i].z - prevPoint.z);
                    Ray2D   rayF    = new Ray2D(new Vector2(prevPoint.x, prevPoint.z), forward);

                    if ((Utils.PointRightTo(rayF, new Vector2(nextPoint.x, nextPoint.z))) == (Vector2.Angle(new Vector2(-directions[i].z, directions[i].x), rayF.direction) >= 90f))
                    {
                        angle = 0f;
                    }
                }
                else
                {
                    if (i == 0)
                    {
                        toRight = (points[i + 1] - points[0]).normalized;
                    }
                    else if (i == points.Length - 1)
                    {
                        toRight = (points[points.Length - 1] - points[points.Length - 2]).normalized;
                    }
                    else
                    {
                        Vector3 nextPoint = points[i + 1];
                        Vector3 prevPoint = points[i - 1];

                        toRight = (nextPoint - prevPoint).normalized;
                    }
                }

                Vector3 down = Vector3.Cross(toRight, directions[i]).normalized;
                if (down.y > 0f)
                {
                    down *= -1f;
                }

                float minDistance = float.MaxValue;
                int   lineIndex   = -1;
                Line  thisLine    = new Line(new Vector2(points[i].x + directions[i].normalized.x * 0.05f, points[i].z + directions[i].normalized.z * 0.05f), new Vector2(points[i].x + directions[i].normalized.x, points[i].z + directions[i].normalized.z));
                for (int j = 0; j < lines.Length; j++)
                {
                    int     j1 = j == 0 ? lines.Length - 1 : j - 1;
                    int     j2 = (j + 1) % lines.Length;
                    Vector2 intersectPoint;
                    if (j1 != i && j != i && j2 != i && lines[i].Intersects(thisLine, out intersectPoint))
                    {
                        if (Vector2.Distance(intersectPoint, new Vector2(points[i].x, points[i].z)) < minDistance)
                        {
                            minDistance = Vector2.Distance(intersectPoint, new Vector2(points[i].x, points[i].z));
                            lineIndex   = j;
                        }
                    }
                }

                if (lineIndex != -1)
                {
                    if (minDistance < 0.1f)
                    {
                        minDistance = 0.1f;
                    }

                    int     lineIndex2  = (lineIndex + 1) % points.Length;
                    Vector3 lowestPoint = points[lineIndex];
                    if (lowestPoint.y > points[lineIndex2].y)
                    {
                        lowestPoint = points[lineIndex2];
                    }

                    directions[i] = new Vector3(directions[i].normalized.x, (lowestPoint.y - points[i].y) * (1f / minDistance), directions[i].normalized.z);
                }

                uvs.Add(new Vector2(points[i].x, points[i].z));
                vertices.Add(points[i]);

                int   counter = 0;
                float x       = 0f;
                while (stepsAmount == 0 ? x < maxDistance : counter < stepsAmount)
                {
                    float[] func = fallFunction(angleResolution * counter);

                    x = func[0];

                    Vector3 vert = points[i] + directions[i].normalized * func[0] * Mathf.Min((1f / (angle / 4.5f)), 1f) + down * func[1];

                    //vertices.Add(new Vector3(vert.x, (GeneratedTrack.GetTensorHeight(vert) - 1.2f) * (x / maxDistance) + ((maxDistance - x) / maxDistance) * vert.y, vert.z));
                    vertices.Add(new Vector3(vert.x, (GeneratedTrack.GetTensorHeight(vert)) + (x / maxDistance) * -1.2f, vert.z));
                    uvs.Add(new Vector2(vertices[vertices.Count - 1].x, vertices[vertices.Count - 1].z));

                    counter++;
                }

                if (stepsAmount == 0)
                {
                    stepsAmount = counter;
                }


                if (i > 0)
                {
                    for (int j = 0; j < stepsAmount - 1; j++)
                    {
                        if (Vector3.Cross((vertices[vertices.Count - (j + 1)] - vertices[vertices.Count - (j + 1 + stepsAmount + 1)]), (vertices[vertices.Count - (j + 1 + stepsAmount + 1)] - vertices[vertices.Count - (j + 2 + stepsAmount + 1)])).y > 0f)
                        {
                            triangles.Add(vertices.Count - (j + 1 + stepsAmount + 1));
                            triangles.Add(vertices.Count - (j + 2 + stepsAmount + 1));
                            triangles.Add(vertices.Count - (j + 1));
                        }
                        else
                        {
                            triangles.Add(vertices.Count - (j + 1 + stepsAmount + 1));
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(vertices.Count - (j + 2 + stepsAmount + 1));
                        }

                        if (Vector3.Cross((vertices[vertices.Count - (j + 2)] - vertices[vertices.Count - (j + 1)]), (vertices[vertices.Count - (j + 1)] - vertices[vertices.Count - (j + 2 + stepsAmount + 1)])).y > 0f)
                        {
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(vertices.Count - (j + 2 + stepsAmount + 1));
                            triangles.Add(vertices.Count - (j + 2));
                        }
                        else
                        {
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(vertices.Count - (j + 2));
                            triangles.Add(vertices.Count - (j + 2 + stepsAmount + 1));
                        }
                    }
                }
                if (i == points.Length - 1 && circle)
                {
                    for (int j = 0; j < stepsAmount - 1; j++)
                    {
                        if (Vector3.Cross((vertices[stepsAmount - (j + 1)] - vertices[vertices.Count - (j + 1)]), (vertices[vertices.Count - (j + 1)] - vertices[vertices.Count - (j + 2)])).y > 0f)
                        {
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(vertices.Count - (j + 2));
                            triangles.Add(stepsAmount - (j + 1));
                        }
                        else
                        {
                            triangles.Add(vertices.Count - (j + 1));
                            triangles.Add(stepsAmount - (j + 1));
                            triangles.Add(vertices.Count - (j + 2));
                        }

                        if (Vector3.Cross((vertices[stepsAmount - (j + 2)] - vertices[stepsAmount - (j + 1)]), (vertices[stepsAmount - (j + 1)] - vertices[vertices.Count - (j + 2)])).y > 0f)
                        {
                            triangles.Add(stepsAmount - (j + 1));
                            triangles.Add(vertices.Count - (j + 2));
                            triangles.Add(stepsAmount - (j + 2));
                        }
                        else
                        {
                            triangles.Add(stepsAmount - (j + 1));
                            triangles.Add(stepsAmount - (j + 2));
                            triangles.Add(vertices.Count - (j + 2));
                        }
                    }
                }
            }


            GetComponent <MeshFilter>().mesh.Clear();
            GetComponent <MeshFilter>().mesh.vertices = vertices.ToArray();

            for (int i = 0; i < uvs.Count; i++)
            {
                //uvs[i] = uvs[i] / 15f;
            }

            GetComponent <MeshFilter>().mesh.uv = uvs.ToArray();

            GetComponent <MeshFilter>().mesh.subMeshCount = 1;

            GetComponent <MeshFilter>().mesh.SetTriangles(triangles.ToArray(), 0);

            GetComponent <MeshFilter>().mesh.RecalculateNormals();

            GetComponent <MeshCollider>().sharedMesh = GetComponent <MeshFilter>().mesh;
        }
    }
Пример #14
0
        //Modified Tube-generation algorithm from http://wiki.unity3d.com/index.php/ProceduralPrimitives
        //closedTube: If true, ignores startRadian & endRadian and creates a regular closed tube. If false, creates an open tube segment ranging from startRadian to endRadian.
        public static GameObject generateTube(float innerRadiusBottom, float outerRadiusBottom, float innerRadiusTop, float outerRadiusTop, float height,
                                              float startRadian, float endRadian, int sides, bool closedTube)
        {
            GameObject result = new GameObject();

            MeshFilter   filter = result.AddComponent <MeshFilter>();
            MeshRenderer mr     = result.AddComponent <MeshRenderer>();

            Mesh mesh = filter.mesh;

            mesh.Clear();

            if (closedTube)
            {
                startRadian = 0f;
                endRadian   = Mathf.PI * 2f;
            }

            int nbVerticesCap   = sides * 2 + 2;
            int nbVerticesSides = sides * 2 + 2;

            #region Vertices

            // bottom + top + sides + segment caps
            int       nbVertOpenTube   = nbVerticesCap * 2 + nbVerticesSides * 2 + 8;
            int       nbVertClosedTube = nbVerticesCap * 2 + nbVerticesSides * 2;
            Vector3[] vertices;
            if (closedTube)
            {
                vertices = new Vector3[nbVertClosedTube];
            }
            else
            {
                vertices = new Vector3[nbVertOpenTube];
            }
            int vert = 0;

            // Bottom cap
            int sideCounter = 0;
            while (vert < nbVerticesCap)
            {
                if (sideCounter == sides && closedTube)
                {
                    sideCounter = 0;
                }

                float r1  = startRadian + ((float)(sideCounter++) / sides * (endRadian - startRadian));
                float cos = Mathf.Cos(r1);
                float sin = Mathf.Sin(r1);
                vertices[vert]     = new Vector3(cos * (innerRadiusBottom), 0f, sin * (innerRadiusBottom));
                vertices[vert + 1] = new Vector3(cos * (outerRadiusBottom), 0f, sin * (outerRadiusBottom));
                vert += 2;
            }

            // Top cap
            sideCounter = 0;
            while (vert < nbVerticesCap * 2)
            {
                if (sideCounter == sides && closedTube)
                {
                    sideCounter = 0;
                }

                float r1  = startRadian + ((float)(sideCounter++) / sides * (endRadian - startRadian));
                float cos = Mathf.Cos(r1);
                float sin = Mathf.Sin(r1);
                vertices[vert]     = new Vector3(cos * (innerRadiusTop), height, sin * (innerRadiusTop));
                vertices[vert + 1] = new Vector3(cos * (outerRadiusTop), height, sin * (outerRadiusTop));
                vert += 2;
            }

            // Sides (out)
            sideCounter = 0;
            while (vert < nbVerticesCap * 2 + nbVerticesSides)
            {
                if (sideCounter == sides && closedTube)
                {
                    sideCounter = 0;
                }

                float r1  = startRadian + ((float)(sideCounter++) / sides * (endRadian - startRadian));
                float cos = Mathf.Cos(r1);
                float sin = Mathf.Sin(r1);
                vertices[vert]     = new Vector3(cos * (outerRadiusTop), height, sin * (outerRadiusTop));
                vertices[vert + 1] = new Vector3(cos * (outerRadiusBottom), 0, sin * (outerRadiusBottom));
                vert += 2;
            }

            // Sides (in)
            sideCounter = 0;
            while (vert < nbVertClosedTube)
            {
                if (sideCounter == sides && closedTube)
                {
                    sideCounter = 0;
                }

                float r1  = startRadian + ((float)(sideCounter++) / sides * (endRadian - startRadian));
                float cos = Mathf.Cos(r1);
                float sin = Mathf.Sin(r1);
                vertices[vert]     = new Vector3(cos * (innerRadiusTop), height, sin * (innerRadiusTop));
                vertices[vert + 1] = new Vector3(cos * (innerRadiusBottom), 0, sin * (innerRadiusBottom));
                vert += 2;
            }

            // Open segments
            if (!closedTube)
            {
                vertices[vert++] = vertices[0];
                vertices[vert++] = vertices[1];
                vertices[vert++] = vertices[nbVerticesCap];
                vertices[vert++] = vertices[nbVerticesCap + 1];

                vertices[vert++] = vertices[nbVerticesCap - 2];
                vertices[vert++] = vertices[nbVerticesCap - 1];
                vertices[vert++] = vertices[2 * nbVerticesCap - 2];
                vertices[vert]   = vertices[2 * nbVerticesCap - 1];
            }
            #endregion

            #region Normales

            // bottom + top + sides
            Vector3[] normales = new Vector3[vertices.Length];
            vert = 0;

            // Bottom cap
            while (vert < nbVerticesCap)
            {
                normales[vert++] = Vector3.down;
            }

            // Top cap
            while (vert < nbVerticesCap * 2)
            {
                normales[vert++] = Vector3.up;
            }

            // Sides (out)
            sideCounter = 0;
            while (vert < nbVerticesCap * 2 + nbVerticesSides)
            {
                if (sideCounter == sides && closedTube)
                {
                    sideCounter = 0;
                }

                float r1 = startRadian + ((float)(sideCounter++) / sides * (endRadian - startRadian));
                normales[vert]     = new Vector3(Mathf.Cos(r1), 0f, Mathf.Sin(r1));
                normales[vert + 1] = normales[vert];
                vert += 2;
            }

            // Sides (in)
            sideCounter = 0;
            while (vert < nbVertClosedTube)
            {
                if (sideCounter == sides && closedTube)
                {
                    sideCounter = 0;
                }

                float r1 = startRadian + ((float)(sideCounter++) / sides * (endRadian - startRadian));
                normales[vert]     = -(new Vector3(Mathf.Cos(r1), 0f, Mathf.Sin(r1)));
                normales[vert + 1] = normales[vert];
                vert += 2;
            }

            // Open segments
            if (!closedTube)
            {
                Vector3 vecA   = vertices[nbVertOpenTube - 7] - vertices[nbVertOpenTube - 8];
                Vector3 vecB   = vertices[nbVertOpenTube - 6] - vertices[nbVertOpenTube - 8];
                Vector3 normal = Vector3.Cross(vecB, vecA);
                normal           = Vector3.Normalize(normal);
                normales[vert++] = normal;
                normales[vert++] = normal;
                normales[vert++] = normal;
                normales[vert++] = normal;

                vecA             = vertices[nbVertOpenTube - 4] - vertices[nbVertOpenTube - 3];
                vecB             = vertices[nbVertOpenTube - 1] - vertices[nbVertOpenTube - 3];
                normal           = Vector3.Cross(vecB, vecA);
                normal           = Vector3.Normalize(normal);
                normales[vert++] = normal;
                normales[vert++] = normal;
                normales[vert++] = normal;
                normales[vert]   = normal;
            }

            #endregion

            #region UVs
            Vector2[] uvs = new Vector2[vertices.Length];

            vert = 0;
            // Bottom cap
            sideCounter = 0;
            while (vert < nbVerticesCap)
            {
                float t = (float)(sideCounter++) / sides;
                uvs[vert++] = new Vector2(0f, t);
                uvs[vert++] = new Vector2(1f, t);
            }

            // Top cap
            sideCounter = 0;
            while (vert < nbVerticesCap * 2)
            {
                float t = (float)(sideCounter++) / sides;
                uvs[vert++] = new Vector2(0f, t);
                uvs[vert++] = new Vector2(1f, t);
            }

            // Sides (out)
            sideCounter = 0;
            while (vert < nbVerticesCap * 2 + nbVerticesSides)
            {
                float t = (float)(sideCounter++) / sides;
                uvs[vert++] = new Vector2(t, 0f);
                uvs[vert++] = new Vector2(t, 1f);
            }

            // Sides (in)
            sideCounter = 0;
            while (vert < nbVertClosedTube)
            {
                float t = (float)(sideCounter++) / sides;
                uvs[vert++] = new Vector2(t, 0f);
                uvs[vert++] = new Vector2(t, 1f);
            }

            // Open segments
            if (!closedTube)
            {
                uvs[vert++] = new Vector2(0, 0);
                uvs[vert++] = new Vector2(0, 1);
                uvs[vert++] = new Vector2(1, 0);
                uvs[vert++] = new Vector2(1, 1);

                uvs[vert++] = new Vector2(0, 1);
                uvs[vert++] = new Vector2(0, 0);
                uvs[vert++] = new Vector2(1, 1);
                uvs[vert]   = new Vector2(1, 0);
            }

            #endregion

            #region Triangles
            int nbFace = sides * 4;
            if (!closedTube)
            {
                nbFace += 2;
            }
            int   nbTriangles = nbFace * 2;
            int   nbIndexes   = nbTriangles * 3;
            int[] triangles   = new int[nbIndexes];

            // Bottom cap
            int i = 0;
            sideCounter = 0;
            while (sideCounter < sides)
            {
                int current = sideCounter * 2;
                int next    = sideCounter * 2 + 2;

                triangles[i++] = next + 1;
                triangles[i++] = next;
                triangles[i++] = current;

                triangles[i++] = current + 1;
                triangles[i++] = next + 1;
                triangles[i++] = current;

                sideCounter++;
            }

            // Top cap
            while (sideCounter < sides * 2)
            {
                int current = sideCounter * 2 + 2;
                int next    = sideCounter * 2 + 4;

                triangles[i++] = current;
                triangles[i++] = next;
                triangles[i++] = next + 1;

                triangles[i++] = current;
                triangles[i++] = next + 1;
                triangles[i++] = current + 1;

                sideCounter++;
            }

            // Sides (out)
            while (sideCounter < sides * 3)
            {
                int current = sideCounter * 2 + 4;
                int next    = sideCounter * 2 + 6;

                triangles[i++] = current;
                triangles[i++] = next;
                triangles[i++] = next + 1;

                triangles[i++] = current;
                triangles[i++] = next + 1;
                triangles[i++] = current + 1;

                sideCounter++;
            }


            // Sides (in)
            while (sideCounter < sides * 4)
            {
                int current = sideCounter * 2 + 6;
                int next    = sideCounter * 2 + 8;

                triangles[i++] = next + 1;
                triangles[i++] = next;
                triangles[i++] = current;

                triangles[i++] = current + 1;
                triangles[i++] = next + 1;
                triangles[i++] = current;

                sideCounter++;
            }

            // Segment Caps
            if (!closedTube)
            {
                triangles[i++] = nbVertOpenTube - 5;
                triangles[i++] = nbVertOpenTube - 7;
                triangles[i++] = nbVertOpenTube - 8;
                triangles[i++] = nbVertOpenTube - 5;
                triangles[i++] = nbVertOpenTube - 8;
                triangles[i++] = nbVertOpenTube - 6;

                triangles[i++] = nbVertOpenTube - 2;
                triangles[i++] = nbVertOpenTube - 4;
                triangles[i++] = nbVertOpenTube - 3;
                triangles[i++] = nbVertOpenTube - 2;
                triangles[i++] = nbVertOpenTube - 3;
                triangles[i++] = nbVertOpenTube - 1;
            }

            #endregion

            mesh.vertices  = vertices;
            mesh.normals   = normales;
            mesh.uv        = uvs;
            mesh.triangles = triangles;
            mesh.RecalculateBounds();

            return(result);
        }
Пример #15
0
        public static bool IsTriTriIntersect(Tri tri1, Tri tri2)
        {
            var distanceTri1_2 = CheckDistances(tri1, tri2);

            if (distanceTri1_2 == DistanceType.NON_ZERO_SAME_SIGN)
            {
                return(false);
            }

            var distanceTri2_1 = CheckDistances(tri2, tri1);

            if (distanceTri2_1 == DistanceType.NON_ZERO_SAME_SIGN)
            {
                return(false);
            }

            if (distanceTri1_2 == DistanceType.ZERO || distanceTri2_1 == DistanceType.ZERO)
            {
                return(IsCoplanarIntersect(tri1, tri2));
            }

            var L_intersectLine = Vector3.Cross(tri1.normal, tri2.normal);
            var max             = Math.Abs(L_intersectLine.X);
            var index           = 0;
            var bb = Math.Abs(L_intersectLine.Y);
            var cc = Math.Abs(L_intersectLine.Z);

            if (bb > max)
            {
                max = bb; index = 1;
            }
            if (cc > max)
            {
                max = cc; index = 2;
            }

            float vp0, vp1, vp2, up0, up1, up2;

            vp0 = tri1.v0.ElemByIndex(index);
            vp1 = tri1.v1.ElemByIndex(index);
            vp2 = tri1.v2.ElemByIndex(index);

            up0 = tri2.v0.ElemByIndex(index);
            up1 = tri2.v1.ElemByIndex(index);
            up2 = tri2.v2.ElemByIndex(index);

            // compute interval for triangle 1
            float a = 0, b = 0, c = 0, x0 = 0, x1 = 0;
            float dv0    = Vector3.Dot(tri2.normal, tri1.v0) + tri2.d;
            float dv1    = Vector3.Dot(tri2.normal, tri1.v1) + tri2.d;
            float dv2    = Vector3.Dot(tri2.normal, tri1.v2) + tri2.d;
            float dv0dv1 = dv0 * dv1;
            float dv0dv2 = dv0 * dv2;

            if (ComputeIntervals(vp0, vp1, vp2, dv0, dv1, dv2, dv0dv1, dv0dv2, ref a, ref b, ref c, ref x0, ref x1))
            {
                return(false);
                //return TriTriCoplanar(n1, v0, v1, v2, u0, u1, u2);
            }


            // compute interval for triangle 1
            float du0    = Vector3.Dot(tri1.normal, tri2.v0) + tri1.d;
            float du1    = Vector3.Dot(tri1.normal, tri2.v1) + tri1.d;
            float du2    = Vector3.Dot(tri1.normal, tri2.v2) + tri1.d;
            float du0du1 = du0 * du1;
            float du0du2 = du0 * du2;

            // compute interval for triangle 2
            float d = 0, e = 0, f = 0, y0 = 0, y1 = 0;

            if (ComputeIntervals(up0, up1, up2, du0, du1, du2, du0du1, du0du2, ref d, ref e, ref f, ref y0, ref y1))
            {
                return(false);
                //return TriTriCoplanar(n1, v0, v1, v2, u0, u1, u2);
            }

            float xx, yy, xxyy, tmp;

            xx   = x0 * x1;
            yy   = y0 * y1;
            xxyy = xx * yy;

            tmp = a * xxyy;

            Vector2 isect1 = Vector2.Zero, isect2 = Vector2.Zero;


            isect1.X = tmp + b * x1 * yy;
            isect1.Y = tmp + c * x0 * yy;

            tmp      = d * xxyy;
            isect2.X = tmp + e * xx * y1;
            isect2.Y = tmp + f * xx * y0;

            Sort(isect1);
            Sort(isect2);

            return(!(isect1.Y < isect2.X || isect2.Y < isect1.X));
        }
Пример #16
0
        /// <summary>
        ///  Method to curve text along a Unity animation curve.
        /// </summary>
        /// <param name="textComponent"></param>
        /// <returns></returns>
        IEnumerator WarpText()
        {
            VertexCurve.preWrapMode  = WrapMode.Clamp;
            VertexCurve.postWrapMode = WrapMode.Clamp;

            //Mesh mesh = m_TextComponent.textInfo.meshInfo[0].mesh;

            Vector3[] vertices;
            Matrix4x4 matrix;

            m_TextComponent.havePropertiesChanged = true; // Need to force the TextMeshPro Object to be updated.
            CurveScale *= 10;
            float          old_CurveScale = CurveScale;
            float          old_ShearValue = ShearAmount;
            AnimationCurve old_curve      = CopyAnimationCurve(VertexCurve);

            while (true)
            {
                if (!m_TextComponent.havePropertiesChanged && old_CurveScale == CurveScale && old_curve.keys[1].value == VertexCurve.keys[1].value && old_ShearValue == ShearAmount)
                {
                    yield return(null);

                    continue;
                }

                old_CurveScale = CurveScale;
                old_curve      = CopyAnimationCurve(VertexCurve);
                old_ShearValue = ShearAmount;

                m_TextComponent.ForceMeshUpdate(); // Generate the mesh and populate the textInfo with data we can use and manipulate.

                TMP_TextInfo textInfo       = m_TextComponent.textInfo;
                int          characterCount = textInfo.characterCount;

                if (characterCount == 0)
                {
                    continue;
                }

                //vertices = textInfo.meshInfo[0].vertices;
                //int lastVertexIndex = textInfo.characterInfo[characterCount - 1].vertexIndex;

                float boundsMinX = m_TextComponent.bounds.min.x; //textInfo.meshInfo[0].mesh.bounds.min.x;
                float boundsMaxX = m_TextComponent.bounds.max.x; //textInfo.meshInfo[0].mesh.bounds.max.x;

                for (int i = 0; i < characterCount; i++)
                {
                    if (!textInfo.characterInfo[i].isVisible)
                    {
                        continue;
                    }

                    int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                    // Get the index of the mesh used by this character.
                    int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;

                    vertices = textInfo.meshInfo[materialIndex].vertices;

                    // Compute the baseline mid point for each character
                    Vector3 offsetToMidBaseline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine);
                    //float offsetY = VertexCurve.Evaluate((float)i / characterCount + loopCount / 50f); // Random.Range(-0.25f, 0.25f);

                    // Apply offset to adjust our pivot point.
                    vertices[vertexIndex + 0] += -offsetToMidBaseline;
                    vertices[vertexIndex + 1] += -offsetToMidBaseline;
                    vertices[vertexIndex + 2] += -offsetToMidBaseline;
                    vertices[vertexIndex + 3] += -offsetToMidBaseline;

                    // Apply the Shearing FX
                    float   shear_value = ShearAmount * 0.01f;
                    Vector3 topShear    = new Vector3(shear_value * (textInfo.characterInfo[i].topRight.y - textInfo.characterInfo[i].baseLine), 0, 0);
                    Vector3 bottomShear = new Vector3(shear_value * (textInfo.characterInfo[i].baseLine - textInfo.characterInfo[i].bottomRight.y), 0, 0);

                    vertices[vertexIndex + 0] += -bottomShear;
                    vertices[vertexIndex + 1] += topShear;
                    vertices[vertexIndex + 2] += topShear;
                    vertices[vertexIndex + 3] += -bottomShear;

                    // Compute the angle of rotation for each character based on the animation curve
                    float x0 = (offsetToMidBaseline.x - boundsMinX) / (boundsMaxX - boundsMinX); // Character's position relative to the bounds of the mesh.
                    float x1 = x0 + 0.0001f;
                    float y0 = VertexCurve.Evaluate(x0) * CurveScale;
                    float y1 = VertexCurve.Evaluate(x1) * CurveScale;

                    Vector3 horizontal = new Vector3(1, 0, 0);
                    //Vector3 normal = new Vector3(-(y1 - y0), (x1 * (boundsMaxX - boundsMinX) + boundsMinX) - offsetToMidBaseline.x, 0);
                    Vector3 tangent = new Vector3(x1 * (boundsMaxX - boundsMinX) + boundsMinX, y1) - new Vector3(offsetToMidBaseline.x, y0);

                    float   dot   = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * 57.2957795f;
                    Vector3 cross = Vector3.Cross(horizontal, tangent);
                    float   angle = cross.z > 0 ? dot : 360 - dot;

                    matrix = Matrix4x4.TRS(new Vector3(0, y0, 0), Quaternion.Euler(0, 0, angle), Vector3.one);

                    vertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
                    vertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
                    vertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
                    vertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);

                    vertices[vertexIndex + 0] += offsetToMidBaseline;
                    vertices[vertexIndex + 1] += offsetToMidBaseline;
                    vertices[vertexIndex + 2] += offsetToMidBaseline;
                    vertices[vertexIndex + 3] += offsetToMidBaseline;
                }

                // Upload the mesh with the revised information
                m_TextComponent.UpdateVertexData();

                yield return(null); // new WaitForSeconds(0.025f);
            }
        }
Пример #17
0
        //-----------------------------------------------------------------
        void Update()
    {
                                                 //判断旋转
                if (Input.GetMouseButtonDown(1)) //鼠标右键刚刚按下了
        {
                    {
                if (m_bMouseRightKeyDown == false)
                {
                    m_bMouseRightKeyDown = true;
                    Vector3 kMousePos = Input.mousePosition;
                    m_fLastMousePosX = kMousePos.x;
                    m_fLastMousePosY = kMousePos.y;
                }
            }
        }
        else if (Input.GetMouseButtonUp(1)) //鼠标右键刚刚抬起了
        {
                    {
                if (m_bMouseRightKeyDown == true)
                {
                    m_bMouseRightKeyDown = false;
                    m_fLastMousePosX     = 0;
                    m_fLastMousePosY     = 0;
                }
            }
        }
        else if (Input.GetMouseButton(1)) //鼠标右键处于按下状态中
        {
                    {
                if (m_bMouseRightKeyDown)
                {
                    Vector3 kMousePos = Input.mousePosition;
                    float   fDeltaX   = kMousePos.x - m_fLastMousePosX;
                    float   fDeltaY   = kMousePos.y - m_fLastMousePosY;
                    m_fLastMousePosX = kMousePos.x;
                    m_fLastMousePosY = kMousePos.y;


                    Vector3 kNewEuler = transform.eulerAngles;
                    kNewEuler.x          += -(fDeltaY * rotateSpeed);
                    kNewEuler.y          += (fDeltaX * rotateSpeed);
                    transform.eulerAngles = kNewEuler;
                }
            }
        }


        //判断位移
        float fMoveDeltaX        = 0.0f;
        float fMoveDeltaZ        = 0.0f;
        float fMoveDeltaVertical = 0f;
        float fDeltaTime         = Time.deltaTime;

        if (Input.GetKey(KeyCode.A))
        {
            fMoveDeltaX -= moveSpeed * fDeltaTime;
        }
        if (Input.GetKey(KeyCode.D))
        {
            fMoveDeltaX += moveSpeed * fDeltaTime;
        }
        if (Input.GetKey(KeyCode.W))
        {
            fMoveDeltaZ += moveSpeed * fDeltaTime;
        }
        if (Input.GetKey(KeyCode.S))
        {
            fMoveDeltaZ -= moveSpeed * fDeltaTime;
        }
        if (Input.GetKey(KeyCode.Q))
        {
            fMoveDeltaVertical -= moveSpeed * fDeltaTime;
        }
        if (Input.GetKey(KeyCode.E))
        {
            fMoveDeltaVertical += moveSpeed * fDeltaTime;
        }
        if (fMoveDeltaX != 0.0f || fMoveDeltaZ != 0.0f || fMoveDeltaVertical != 0.0f)
        {
            Vector3 kForward = transform.forward;
            Vector3 kRight   = Vector3.Cross(kUpDirection, kForward);
            Vector3 kNewPos  = transform.position;
            kNewPos           += kRight * fMoveDeltaX;
            kNewPos           += kForward * fMoveDeltaZ;
            kNewPos.y         += fMoveDeltaVertical;
            transform.position = kNewPos;
        }
    }
Пример #18
0
        private void On_MouseMove(object sender, MouseEventArgs e)
        {
            Point pos = e.Location;

            if (m_leftDown)
            {
                // Calculate yaw to look around with a mouse
                m_direction = Vector3.Transform(m_direction, Matrix3.CreateFromAxisAngle(m_up, -m_mouseSpeedX * (pos.X - m_prevMouseP.X)));

                // Pitch is limited to m_pitchLimit
                float angle = m_mouseSpeedY * (pos.Y - m_prevMouseP.Y);
                if ((Pitch < m_pitchLimit || angle > 0) && (Pitch > -m_pitchLimit || angle < 0))
                {
                    m_direction = Vector3.Transform(m_direction, Matrix3.CreateFromAxisAngle(Vector3.Cross(m_up, m_direction), angle));
                }
            }
            m_prevMouseP = pos;
        }
Пример #19
0
 public static float AngleSigned(Vector3 v1, Vector3 v2, Vector3 n)
 {
     return(Mathf.Atan2(
                Vector3.Dot(n, Vector3.Cross(v1, v2)),
                Vector3.Dot(v1, v2)) * Mathf.Rad2Deg);
 }
Пример #20
0
 //static type-specific methods
 /// <summary>
 /// Determines the cross-product of two Vector3
 /// </summary>
 /// <param name="a">the first vector to be used in the cross-product calculation</param>
 /// <param name="b">the second vector to be used in the cross-product calculation</param>
 /// <returns>the cross-product of two vector</returns>
 public static Vector3 Cross(Vector3 a, Vector3 b)
 {
     return a.Cross(b);
 }
Пример #21
0
        /// <summary>
        /// Gets the shortest arc quaternion to rotate this vector to the destination vector. 
        /// </summary>
        /// <param name="destination"></param>
        /// <param name="fallbackAxis"></param>
        /// <returns></returns>
        /// <remarks>
        ///		Don't call this if you think the dest vector can be close to the inverse
        ///		of this vector, since then ANY axis of rotation is ok.
        ///	</remarks>
        public Quaternion GetRotationTo( Vector3 destination, Vector3 fallbackAxis )
        {
            // Based on Stan Melax's article in Game Programming Gems
            Quaternion q;

            // Copy, since cannot modify local
            Vector3 v0 = new Vector3( this.x, this.y, this.z );
            Vector3 v1 = destination;

            // normalize both vectors
            v0.Normalize();
            v1.Normalize();

            // get the cross product of the vectors
            Vector3 c = v0.Cross( v1 );

            Real d = v0.Dot( v1 );

            // If dot == 1, vectors are the same
            if( d >= 1.0f )
            {
                return Quaternion.Identity;
            }

            if( d < ( 1e-6f - 1.0f ) )
            {
                if( fallbackAxis != Vector3.Zero )
                {
                    // rotate 180 degrees about the fallback axis
                    q = Quaternion.FromAngleAxis( Utility.PI, fallbackAxis );
                }
                else
                {
                    // Generate an axis
                    Vector3 axis = Vector3.UnitX.Cross( this );
                    if( axis.IsZeroLength ) // pick another if colinear
                    {
                        axis = Vector3.UnitY.Cross( this );
                    }
                    axis.Normalize();
                    q = Quaternion.FromAngleAxis( Utility.PI, axis );
                }
            }
            else
            {
                Real s = Utility.Sqrt( ( 1 + d ) * 2 );
                Real inverse = 1 / s;

                q.x = c.x * inverse;
                q.y = c.y * inverse;
                q.z = c.z * inverse;
                q.w = s * 0.5f;
            }
            return q;
        }
Пример #22
0
        IEnumerator TransformSelected(TransformType transType)
        {
            isTransforming      = true;
            totalScaleAmount    = 0;
            totalRotationAmount = Quaternion.identity;

            Vector3 originalPivot = pivotPoint;

            Vector3 planeNormal           = (transform.position - originalPivot).normalized;
            Vector3 axis                  = GetNearAxisDirection();
            Vector3 projectedAxis         = Vector3.ProjectOnPlane(axis, planeNormal).normalized;
            Vector3 previousMousePosition = Vector3.zero;

            List <ICommand> transformCommands = new List <ICommand>();

            for (int i = 0; i < targetRootsOrdered.Count; i++)
            {
                transformCommands.Add(new TransformCommand(this, targetRootsOrdered[i]));
            }

            while (!Input.GetMouseButtonUp(0))
            {
                Ray     mouseRay      = myCamera.ScreenPointToRay(Input.mousePosition);
                Vector3 mousePosition = Geometry.LinePlaneIntersect(mouseRay.origin, mouseRay.direction, originalPivot, planeNormal);

                if (previousMousePosition != Vector3.zero && mousePosition != Vector3.zero)
                {
                    if (transType == TransformType.Move)
                    {
                        float   moveAmount = ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projectedAxis) * moveSpeedMultiplier;
                        Vector3 movement   = axis * moveAmount;

                        for (int i = 0; i < targetRootsOrdered.Count; i++)
                        {
                            Transform target = targetRootsOrdered[i];

                            target.Translate(movement, Space.World);
                        }

                        SetPivotPointOffset(movement);
                    }
                    else if (transType == TransformType.Scale)
                    {
                        Vector3 projected   = (nearAxis == Axis.Any) ? transform.right : projectedAxis;
                        float   scaleAmount = ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projected) * scaleSpeedMultiplier;

                        //WARNING - There is a bug in unity 5.4 and 5.5 that causes InverseTransformDirection to be affected by scale which will break negative scaling. Not tested, but updating to 5.4.2 should fix it - https://issuetracker.unity3d.com/issues/transformdirection-and-inversetransformdirection-operations-are-affected-by-scale
                        Vector3 localAxis = (space == TransformSpace.Local && nearAxis != Axis.Any) ? mainTargetRoot.InverseTransformDirection(axis) : axis;

                        Vector3 targetScaleAmount = Vector3.one;
                        if (nearAxis == Axis.Any)
                        {
                            targetScaleAmount = (ExtVector3.Abs(mainTargetRoot.localScale.normalized) * scaleAmount);
                        }
                        else
                        {
                            targetScaleAmount = localAxis * scaleAmount;
                        }

                        for (int i = 0; i < targetRootsOrdered.Count; i++)
                        {
                            Transform target = targetRootsOrdered[i];

                            Vector3 targetScale = target.localScale + targetScaleAmount;

                            if (pivot == TransformPivot.Pivot)
                            {
                                target.localScale = targetScale;
                            }
                            else if (pivot == TransformPivot.Center)
                            {
                                if (scaleType == ScaleType.FromPoint)
                                {
                                    target.SetScaleFrom(originalPivot, targetScale);
                                }
                                else if (scaleType == ScaleType.FromPointOffset)
                                {
                                    target.SetScaleFromOffset(originalPivot, targetScale);
                                }
                            }
                        }

                        totalScaleAmount += scaleAmount;
                    }
                    else if (transType == TransformType.Rotate)
                    {
                        float   rotateAmount = 0;
                        Vector3 rotationAxis = axis;

                        if (nearAxis == Axis.Any)
                        {
                            Vector3 rotation = transform.TransformDirection(new Vector3(Input.GetAxis("Mouse Y"), -Input.GetAxis("Mouse X"), 0));
                            Quaternion.Euler(rotation).ToAngleAxis(out rotateAmount, out rotationAxis);
                            rotateAmount *= allRotateSpeedMultiplier;
                        }
                        else
                        {
                            if (circularRotationMethod)
                            {
                                float angle = Vector3.SignedAngle(previousMousePosition - originalPivot, mousePosition - originalPivot, axis);
                                rotateAmount = angle * rotateSpeedMultiplier;
                            }
                            else
                            {
                                Vector3 projected = (nearAxis == Axis.Any || ExtVector3.IsParallel(axis, planeNormal)) ? planeNormal : Vector3.Cross(axis, planeNormal);
                                rotateAmount = (ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projected) * (rotateSpeedMultiplier * 100f)) / GetDistanceMultiplier();
                            }
                        }

                        for (int i = 0; i < targetRootsOrdered.Count; i++)
                        {
                            Transform target = targetRootsOrdered[i];

                            if (pivot == TransformPivot.Pivot)
                            {
                                target.Rotate(rotationAxis, rotateAmount, Space.World);
                            }
                            else if (pivot == TransformPivot.Center)
                            {
                                target.RotateAround(originalPivot, rotationAxis, rotateAmount);
                            }
                        }

                        totalRotationAmount *= Quaternion.Euler(rotationAxis * rotateAmount);
                    }
                }

                previousMousePosition = mousePosition;

                yield return(null);
            }

            for (int i = 0; i < transformCommands.Count; i++)
            {
                ((TransformCommand)transformCommands[i]).StoreNewTransformValues();
            }
            CommandGroup commandGroup = new CommandGroup();

            commandGroup.Set(transformCommands);
            UndoRedoManager.Insert(commandGroup);

            totalRotationAmount = Quaternion.identity;
            totalScaleAmount    = 0;
            isTransforming      = false;
            SetTranslatingAxis(transformType, Axis.None);

            SetPivotPoint();
        }
Пример #23
0
        /// <summary>
        ///     Gets the shortest arc quaternion to rotate this vector
        ///     to the destination vector.
        /// </summary>   
        /// <remarks>
        ///     If you call this with a dest vector that is close to the inverse
        ///     of this vector, we will rotate 180 degrees around the 'fallbackAxis'
        ///     (if specified, or a generated axis if not) since in this case
        ///     ANY axis of rotation is valid.
        /// </remarks>
        public Quaternion GetRotationTo(Vector3 destination, Vector3 fallbackAxis)
        {
            // Based on Stan Melax's article in Game Programming Gems
            Quaternion q = new Quaternion();

            Vector3 v0 = new Vector3(this.x, this.y, this.z);
            Vector3 v1 = destination;

            // normalize both vectors
            v0.Normalize();
            v1.Normalize();

            // get the cross product of the vectors
            Vector3 c = v0.Cross(v1);

            // If the cross product approaches zero, we get unstable because ANY axis will do
            // when v0 == -v1
            float d = v0.Dot(v1);

            // If dot == 1, vectors are the same
            if (d >= 1.0f)
            {
                return Quaternion.Identity;
            }

            if (d < (1e-6f - 1.0f))
            {
                if (fallbackAxis != Vector3.Zero)
                    // rotate 180 degrees about the fallback axis
                    q = Quaternion.FromAngleAxis((float)Math.PI, fallbackAxis);
                else
                {
                    // Generate an axis
                    Vector3 axis = Vector3.UnitX.Cross(this);
                    if (axis.IsZero) // pick another if colinear
                        axis = Vector3.UnitY.Cross(this);
                    axis.Normalize();
                    q = Quaternion.FromAngleAxis((float)Math.PI, axis);
                }
            }
            else
            {
                float s = MathUtil.Sqrt( (1+d) * 2 );
                float inverse = 1 / s;

                q.x = c.x * inverse;
                q.y = c.y * inverse;
                q.z = c.z * inverse;
                q.w = s * 0.5f;
                q.Normalize();
            }
            return q;
        }
Пример #24
0
    public Path processPoints()
    {
        if (nature == Nature.Normal)
        {
            path = new Path(Vector3.zero); //Create new path to exploit
            if (points.Count > 1)
            {
                Vector3 direction       = points[1] - points[0]; // Get first direction from start to second point
                bool    changeDirection = false;

                List <Vector3> pathPoints = new List <Vector3>();

                pathPoints.Add(points[0]);
                // Add first ANCHOR
                pathPoints.Add(new Vector3(points[0].x + (points[1].x - points[0].x) / 2f,
                                           points[0].y + (points[1].y - points[0].y) / 2f,
                                           points[0].z + (points[1].z - points[0].z) / 2f));
                // Add first PIVOT
                if (points.Count > 2)
                {
                    if (Vector3.Cross(direction.normalized, (points[2] - points[1]).normalized) != Vector3.zero) // first is short
                    {
                        direction = points[2] - points[1];                                                       //New direction
                        pathPoints.Add(points[1]);                                                               //PIVOT
                        pathPoints.Add(new Vector3(points[1].x + (points[2].x - points[1].x) / 2f,
                                                   points[1].y + (points[2].y - points[1].y) / 2f,
                                                   points[1].z + (points[2].z - points[1].z) / 2f)); //ANCHOR
                        pathPoints.Add(points[2]);                                                   //PIVOT
                    }
                    for (int i = 2; i < points.Count - 2;)
                    {
                        if (Vector3.Cross(direction.normalized, (points[i + 1] - points[i]).normalized) == Vector3.zero) // if on same line so go to next point
                        {
                            changeDirection = false;
                            i++;
                        }
                        else if (Vector3.Cross(direction.normalized, (points[i + 1] - points[i]).normalized) != Vector3.zero)
                        {
                            if (changeDirection)
                            {
                                pathPoints.Add(points[i]);//PIVOT
                                pathPoints.Add(new Vector3(points[i].x + (points[i + 1].x - points[i].x) / 2f,
                                                           points[i].y + (points[i + 1].y - points[i].y) / 2f,
                                                           points[i].z + (points[i + 1].z - points[i].z) / 2f)); //ANCHOR
                                pathPoints.Add(points[i + 1]);                                                   //PIVOT


                                direction = points[i + 1] - points[i];

                                i++;
                            }
                            else
                            {
                                i--;
                                pathPoints.Add(new Vector3(points[i - 1].x + (points[i].x - points[i - 1].x) / 4f,
                                                           points[i - 1].y + (points[i].y - points[i - 1].y) / 4f,
                                                           points[i - 1].z + (points[i].z - points[i - 1].z) / 4f)); //PIVOT
                                pathPoints.Add(points[i]);                                                           //ANCHOR
                                pathPoints.Add(new Vector3(points[i].x + (points[i + 1].x - points[i].x) / (4f / 3f),
                                                           points[i].y + (points[i + 1].y - points[i].y) / (4f / 3f),
                                                           points[i].z + (points[i + 1].z - points[i].z) / (4f / 3f))); //PIVOT

                                i++;
                                i++;
                                pathPoints.Add(new Vector3(points[i - 1].x + (points[i].x - points[i - 1].x) / 4f,
                                                           points[i - 1].y + (points[i].y - points[i - 1].y) / 4f,
                                                           points[i - 1].z + (points[i].z - points[i - 1].z) / 4f)); //PIVOT
                                pathPoints.Add(points[i]);                                                           //ANCHOR
                                pathPoints.Add(new Vector3(points[i].x + (points[i + 1].x - points[i].x) / (4f / 3f),
                                                           points[i].y + (points[i + 1].y - points[i].y) / (4f / 3f),
                                                           points[i].z + (points[i + 1].z - points[i].z) / (4f / 3f))); //PIVOT

                                direction = points[i + 1] - points[i];

                                i++;
                                changeDirection = true;
                            }
                        }
                    }

                    if (Vector3.Cross((points[points.Count - 2] - points[points.Count - 3]).normalized, (points[points.Count - 1] - points[points.Count - 2]).normalized) != Vector3.zero) // last is short
                    {
                        pathPoints.Add(points[points.Count - 3]);                                                                                                                          //PIVOT
                        pathPoints.Add(new Vector3(points[points.Count - 3].x + (points[points.Count - 2].x - points[points.Count - 3].x) / 2f,
                                                   points[points.Count - 3].y + (points[points.Count - 2].y - points[points.Count - 3].y) / 2f,
                                                   points[points.Count - 3].z + (points[points.Count - 2].z - points[points.Count - 3].z) / 2f)); //ANCHOR
                        pathPoints.Add(points[points.Count - 2]);                                                                                 //PIVOT
                    }
                }
                pathPoints.Add(new Vector3(points[points.Count - 2].x + (points[points.Count - 1].x - points[points.Count - 2].x) / 2f,
                                           points[points.Count - 2].y + (points[points.Count - 1].y - points[points.Count - 2].y) / 2f,
                                           points[points.Count - 2].z + (points[points.Count - 1].z - points[points.Count - 2].z) / 2f));
                // Add last PIVOT
                pathPoints.Add(points[points.Count - 1]);
                //add last ANCHOR

                if (debug) ////////DEBUG///////
                {
                    for (int i = 0; i < pathPoints.Count; i++)
                    {
                        GameObject g;
                        g = GameObject.CreatePrimitive(PrimitiveType.Cube);
                        g.transform.position = pathPoints[i];
                        g.name = i.ToString();
                    }

                    for (int i = 0; i < pathPoints.Count; i++)
                    {
                        GameObject g;
                        if (i % 3 == 0)
                        {
                            g = GameObject.CreatePrimitive(PrimitiveType.Cube);
                        }
                        else
                        {
                            g = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                        }

                        g.transform.position = pathPoints[i];
                    }
                }

                if (points.Count > 2)
                {
                    for (int i = 1; i < pathPoints.Count / 3; i++)
                    {
                        path.AddSegment(Vector3.zero);
                    }
                }

                for (int i = 0; i < path.NumPoints; i++)
                {
                    path[i] = pathPoints[i];
                }
            }
        }
        if (nature == Nature.Anchor)
        {
            path = new Path(Vector3.zero);

            if (debug) ////////DEBUG///////
            {
                for (int i = 0; i < points.Count; i++)
                {
                    GameObject g;
                    if (i % 3 == 0)
                    {
                        g = GameObject.CreatePrimitive(PrimitiveType.Cube);
                    }
                    else
                    {
                        g = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                    }

                    g.transform.position = points[i];
                }
            }

            if (points.Count > 4)
            {
                for (int i = 1; i < points.Count / 3; i++)
                {
                    path.AddSegment(Vector3.zero);
                }
            }

            for (int i = 0; i < path.NumPoints; i++)
            {
                path[i] = points[i];
            }
        }

        return(path);
    }
Пример #25
0
        public static Quaternion Align(this Transform transform, Vector3 normAlignVector, TransformAxis alignmentAxis)
        {
            Vector3 axis = transform.up;

            if (alignmentAxis != TransformAxis.PositiveY)
            {
                if (alignmentAxis == TransformAxis.PositiveX)
                {
                    axis = transform.right;
                }
                else if (alignmentAxis == TransformAxis.NegativeX)
                {
                    axis = -transform.right;
                }
                else if (alignmentAxis == TransformAxis.NegativeY)
                {
                    axis = -transform.up;
                }
                else if (alignmentAxis == TransformAxis.PositiveZ)
                {
                    axis = transform.forward;
                }
                else if (alignmentAxis == TransformAxis.NegativeZ)
                {
                    axis = -transform.forward;
                }
            }

            float alignment = Vector3.Dot(axis, normAlignVector);

            if (1.0f - alignment < 1e-5f)
            {
                return(Quaternion.identity);
            }

            Vector3 rotAxis = Vector3.zero;

            // Check if the alignment axis is aligned with the alignment vector in the opposite direction
            if (alignment + 1.0f < 1e-5f)
            {
                if (alignmentAxis == TransformAxis.PositiveX)
                {
                    rotAxis = transform.up;
                }
                else if (alignmentAxis == TransformAxis.NegativeX)
                {
                    rotAxis = -transform.up;
                }
                else if (alignmentAxis == TransformAxis.PositiveY)
                {
                    rotAxis = transform.right;
                }
                else if (alignmentAxis == TransformAxis.NegativeY)
                {
                    rotAxis = -transform.right;
                }
                else if (alignmentAxis == TransformAxis.PositiveZ)
                {
                    rotAxis = transform.up;
                }
                else if (alignmentAxis == TransformAxis.NegativeZ)
                {
                    rotAxis = -transform.up;
                }
            }
            else
            {
                rotAxis = Vector3.Normalize(Vector3.Cross(axis, normAlignVector));
            }

            float rotAngle = Vector3Ex.SignedAngle(axis, normAlignVector, rotAxis);

            transform.Rotate(rotAxis, rotAngle, Space.World);
            return(Quaternion.AngleAxis(rotAngle, rotAxis));
        }
Пример #26
0
        void CalculateCurveFit(Common.Vbo handle)
        {
            int num       = handle.selectedVertices.Count;
            var pointsMat = new MathNet.Numerics.LinearAlgebra.Double.DenseMatrix(num, 3);
            var points    = new Vector3[num];

            //get selected points
            for (int i = 0; i < num; i++)
            {
                pointsMat[i, 0] = handle.verticesData.vertices[handle.selectedVertices[i]].X;
                pointsMat[i, 1] = handle.verticesData.vertices[handle.selectedVertices[i]].Y;
                pointsMat[i, 2] = handle.verticesData.vertices[handle.selectedVertices[i]].Z;

                points[i] = handle.verticesData.vertices[handle.selectedVertices[i]];
            }

            //find the plane which holds the least distance to all ponits using SVD
            Common.Plane curve_plane = NormalPlane(pointsMat);
            curve_plane.valid = true;
            Planes[GetSelectedVbOIndex() - 1][CURVEPLANE_INDEX] = curve_plane;

            if (Planes[GetSelectedVbOIndex() - 1][OCCLUSALPLANE_INDEX] != null &&
                Planes[GetSelectedVbOIndex() - 1][OCCLUSALPLANE_INDEX].valid)
            {
                double angle = Planes[GetSelectedVbOIndex() - 1][CURVEPLANE_INDEX].Angle2Plane(Planes[0][OCCLUSALPLANE_INDEX]);
                lb_curve2occlusalPlane.Text = "Angle to Occlusal Plane: " + angle.ToString("F2");
            }

            //calculate sum of distances to this plane
            double sumOfSquaredDistances = 0;

            double[] z_distances = new double[num];
            for (int i = 0; i < num; ++i)
            {
                double d = curve_plane.Distance2Point(points[i]);
                z_distances[i]         = d;
                sumOfSquaredDistances += Math.Pow(d, 2);
            }
            double rmse_z = Math.Sqrt(sumOfSquaredDistances / num);


            // find the x and y direction on the plane
            var p0  = new Vector3(curve_plane.ProjectPointOnPlane(new Vector3(0, 0, 0)));
            var px  = new Vector3(curve_plane.ProjectPointOnPlane(points[num - 1] - points[0]));                //new Vector3(1, 0, 0)));
            var py  = new Vector3(curve_plane.ProjectPointOnPlane(Vector3.Cross(curve_plane.GetNormal(), px))); //new Vector3(0, 1, 0)));
            var pvx = (px - p0);
            var pvy = (py - p0);

            pvx.Normalize();
            pvy.Normalize();


            //project 3D points on the plane and create a 2D point set
            var points2DX = new double[num];
            var points2DY = new double[num];

            for (int i = 0; i < num; ++i)
            {
                points2DX[i] = Vector3.Dot(pvx, points[i] - p0);
                points2DY[i] = Vector3.Dot(pvy, points[i] - p0);
            }

            //check and fix inverse y mode
            if (points2DY[0] < points2DY[points2DY.Length / 2])
            {
                points2DY = points2DY.Select(el => - el).ToArray();
            }

            //move points to fit on the screen
            var xMin = points2DX.Min();
            var yMin = points2DY.Min();

            for (int i = 0; i < num; ++i)
            {
                points2DX[i] -= xMin;
                points2DY[i] -= yMin;

                points2DX[i] += 10;
                points2DY[i] += 10;
            }


            //drawing projected points
            var graphics = pl_curveFit.CreateGraphics();

            graphics.Clear(Color.White);
            for (int i = 0; i < num; ++i)
            {
                DrawPoint2DOnControl(graphics, new PointF((float)points2DX[i], (float)points2DY[i]), Color.Black, 4);
            }
            //DrawPoint2DOnControl(graphics, new PointF((float)10, (float)20), Color.Red, 10);

            //change of parameter
            var diffx = Diff(points2DX);
            var diffy = Diff(points2DY);

            diffx = diffx.Select(el => el * el).ToArray();
            diffy = diffy.Select(el => el * el).ToArray();
            double[] t = new double[num];
            for (int i = 0; i < num; ++i)
            {
                if (i > 0)
                {
                    t[i] = Math.Sqrt(diffx[i] + diffy[i]) + t[i - 1];
                }
                else
                {
                    t[i] = Math.Sqrt(diffx[i] + diffy[i]);
                }
            }

            //fit curve params
            int         deg         = (int)nUpDown_order.Value;
            FitFunction fitFunction = config.fitFunction;

            //fit x and y to t
            DenseVector Wx;
            DenseVector Wy;

            try
            {
                //f = Fit.Polynomial(xdata, ydata, order);
                Wx = FitLeastSquaresBasis(t, points2DX, fitFunction, deg);
                Wy = FitLeastSquaresBasis(t, points2DY, fitFunction, deg);
            }
            catch (Exception e)
            {
                Common.Logger.Log("MainForm", "curveFit.cs", "CalculateCurveFit",
                                  e.Message);
                MessageBox.Show("The order of polynomial is too high and " +
                                "results are unstable. Please use a lower " +
                                "degree polynomial.",
                                "Error in Curve Fitting");
                return;
            }

            // create polynomial curve struct (for later to match to the wire brackets)
            CurveFit[GetSelectedVbOIndex() - 1].CoeffsX     = Wx;
            CurveFit[GetSelectedVbOIndex() - 1].CoeffsY     = Wy;
            CurveFit[GetSelectedVbOIndex() - 1].degree      = deg;
            CurveFit[GetSelectedVbOIndex() - 1].minT        = t.Min() - 5;
            CurveFit[GetSelectedVbOIndex() - 1].maxT        = t.Max() + 5;
            CurveFit[GetSelectedVbOIndex() - 1].fitFunction = fitFunction;

            //calculate xx and yy
            //const double stepSize = 0.01;
            //double mint = t.Min();
            //double maxt = t.Max();
            //int numCurve = (int)((maxt - mint) / stepSize);
            //double[] tt = new double[numCurve];
            //for (int i = 0; i < numCurve; i++)
            //{
            //    tt[i] = mint + stepSize * i;
            //}

            //var TT = MakeBasis(tt, fitFunction, deg);
            //var XX = TT * Wx;
            //var YY = TT * Wy;

            Tuple <DenseVector, DenseVector> tempTuple = ParametricPolynomial_to_2DPoints(CurveFit[GetSelectedVbOIndex() - 1]);
            DenseVector XX = tempTuple.Item1;
            DenseVector YY = tempTuple.Item2;

            DrawCurve(graphics, XX, YY, Color.Blue);

            //least squares

            //DenseVector W;
            //try
            //{
            //    //f = Fit.Polynomial(xdata, ydata, order);
            //    W = FitLeastSquaresBasis(xdata, ydata, fitFunction, deg);
            //}
            //catch (Exception e)
            //{
            //    MessageBox.Show("The order of polynomial is too high and results are unstable. Please use a lower degree polynomial.", "Error in Curve Fitting");
            //    return;
            //}


            //draw the blue curve
            //DrawCurve(graphics, W, xdata.Min()-4, xdata.Max()+4, fitFunction, deg);

            //calculate Error
            //var rmse_xy = CalculatePerpendicularDistancePointToCurve(xdata, ydata, W, fitFunction, deg, graphics);
            double[] xy_distances;
            int[]    closestPointsIndexOnCurve;
            var      rmse_xy = CalculatePerpendicularDistancePointToCurve(points2DX, points2DY, XX, YY, graphics,
                                                                          out xy_distances, out closestPointsIndexOnCurve);

            //fill the list view with point distances
            lv_pointDistance.Clear();
            lv_pointDistance.Columns.Add("Pt", 20, HorizontalAlignment.Center);
            lv_pointDistance.Columns.Add("off", 40, HorizontalAlignment.Center);
            lv_pointDistance.Columns.Add("intra", 40, HorizontalAlignment.Center);

            for (int i = 0; i < num; ++i)
            {
                lv_pointDistance.Items.Add(new ListViewItem(new string[]
                {
                    i.ToString(),
                    z_distances[i].ToString("F2"),
                    xy_distances[i].ToString("F2")
                }));
            }
            if (lv_pointDistance.Items.Count > 0)
            {
                lv_pointDistance.Items[0].Selected = true;
            }

            lb_curvefit_rmse_xy.Text = "in-plane RMS Error:   " + rmse_xy.ToString("F2");
            lb_curvefit_rmse_z.Text  = "off-plane RMS Error:  " + rmse_z.ToString("F2");


            // write results to disk
            string resultsDir = "Results";

            if (!System.IO.Directory.Exists(resultsDir))
            {
                System.IO.Directory.CreateDirectory(resultsDir);
            }

            string save_path = System.IO.Path.Combine(
                resultsDir, "CurveFitResults_" + GetSelectedVbOIndex().ToString() + ".csv");
            var writer = new StreamWriter(save_path);

            writer.WriteLine("Point Number,X,Y,Z,Projected on WirePlane (X),Projected on WirePlane (Y)," +
                             "Nearest Point on 2D Wire (projected wire) (X),Nearest Point on 2D Wire(projected wire)(Y)," +
                             "InPlane Distance,OffPlane Distance");

            for (int i = 0; i < num; ++i)
            {
                writer.Write(i.ToString() + ",");
                writer.Write(points[i].X.ToString() + ",");
                writer.Write(points[i].Y.ToString() + ",");
                writer.Write(points[i].Z.ToString() + ",");
                writer.Write(points2DX[i].ToString() + ",");
                writer.Write(points2DY[i].ToString() + ",");
                writer.Write(XX[closestPointsIndexOnCurve[i]].ToString() + ",");
                writer.Write(YY[closestPointsIndexOnCurve[i]].ToString() + ",");
                writer.Write(xy_distances[i].ToString() + ",");
                writer.Write(z_distances[i].ToString());
                writer.WriteLine("");
            }
            writer.Close();
            status.Text = "Results of curve fitting are saved in: " + save_path;
        }
Пример #27
0
        public Vector3 CalculateNormal(Vector3 a, Vector3 b, Vector3 c)
        {
            Vector3 planeNormal = Vector3.Cross(c - a, b - a).normalized * 0.025f;

            return(planeNormal);
        }
Пример #28
0
        public static void RecalculateTangents(this Mesh mesh)
        {
            //speed up math by copying the mesh arrays
            int[]     triangles = mesh.triangles;
            Vector3[] vertices  = mesh.vertices;
            Vector2[] uv        = mesh.uv;
            Vector3[] normals   = mesh.normals;

            //variable definitions
            int triangleCount = triangles.Length;
            int vertexCount   = vertices.Length;

            Vector3[] tan1 = new Vector3[vertexCount];
            Vector3[] tan2 = new Vector3[vertexCount];

            Vector4[] tangents = new Vector4[vertexCount];

            for (long a = 0; a < triangleCount; a += 3)
            {
                long i1 = triangles[a + 0];
                long i2 = triangles[a + 1];
                long i3 = triangles[a + 2];

                Vector3 v1 = vertices[i1];
                Vector3 v2 = vertices[i2];
                Vector3 v3 = vertices[i3];

                Vector2 w1 = uv[i1];
                Vector2 w2 = uv[i2];
                Vector2 w3 = uv[i3];

                float x1 = v2.x - v1.x;
                float x2 = v3.x - v1.x;
                float y1 = v2.y - v1.y;
                float y2 = v3.y - v1.y;
                float z1 = v2.z - v1.z;
                float z2 = v3.z - v1.z;

                float s1 = w2.x - w1.x;
                float s2 = w3.x - w1.x;
                float t1 = w2.y - w1.y;
                float t2 = w3.y - w1.y;

                float r = 1.0f / (s1 * t2 - s2 * t1);

                Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
                Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

                tan1[i1] += sdir;
                tan1[i2] += sdir;
                tan1[i3] += sdir;

                tan2[i1] += tdir;
                tan2[i2] += tdir;
                tan2[i3] += tdir;
            }


            for (long a = 0; a < vertexCount; ++a)
            {
                Vector3 n = normals[a];
                Vector3 t = tan1[a];

                //Vector3 tmp = (t - n * Vector3.Dot(n, t)).normalized;
                //tangents[a] = new Vector4(tmp.x, tmp.y, tmp.z);
                Vector3.OrthoNormalize(ref n, ref t);
                tangents[a].x = t.x;
                tangents[a].y = t.y;
                tangents[a].z = t.z;

                tangents[a].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
            }

            mesh.tangents = tangents;
        }
Пример #29
0
        /// <summary>
        /// Update the rotation forces.
        /// </summary>
        public override void UpdateRotation()
        {
            var updateNormalRotation = m_Stopping;
            var targetNormal         = m_Stopping ? (m_StopGravityDirection.sqrMagnitude > 0 ? -m_StopGravityDirection : -m_CharacterLocomotion.GravityDirection) : m_CharacterLocomotion.Up;

            if (!m_Stopping)
            {
                // If the depth offset isn't zero then use two raycasts to determine the ground normal. This will allow a long character (such as a horse) to correctly
                // adjust to a slope.
                if (m_DepthOffset != 0)
                {
                    var        frontPoint = m_Transform.position;
                    bool       frontHit;
                    RaycastHit raycastHit;
                    if ((frontHit = Physics.Raycast(m_Transform.TransformPoint(0, 0.1f, m_DepthOffset * Mathf.Sign(m_CharacterLocomotion.InputVector.y)),
                                                    -m_CharacterLocomotion.Up, out raycastHit, m_Distance, m_CharacterLayerManager.SolidObjectLayers, QueryTriggerInteraction.Ignore)))
                    {
                        frontPoint   = raycastHit.point;
                        targetNormal = raycastHit.normal;
                    }

                    var backPoint = frontPoint;
                    if (Physics.Raycast(m_Transform.TransformPoint(0, 0.1f, m_DepthOffset * -Mathf.Sign(m_CharacterLocomotion.InputVector.y)),
                                        -m_CharacterLocomotion.Up, out raycastHit, m_Distance, m_CharacterLayerManager.SolidObjectLayers, QueryTriggerInteraction.Ignore))
                    {
                        if (frontHit)
                        {
                            if (m_NormalizeDirection)
                            {
                                backPoint = raycastHit.point;
                                var direction = (frontPoint - backPoint).normalized;
                                targetNormal = Vector3.Cross(direction, Vector3.Cross(m_CharacterLocomotion.Up, direction)).normalized;
                            }
                            else
                            {
                                targetNormal = (targetNormal + raycastHit.normal).normalized;
                            }
                        }
                        else
                        {
                            targetNormal = raycastHit.normal;
                        }
                    }

                    m_CharacterLocomotion.GravityDirection = -targetNormal;
                    updateNormalRotation = true;
                }
                else
                {
                    var hitCount = m_CharacterLocomotion.Cast(-m_CharacterLocomotion.Up * m_Distance,
                                                              m_CharacterLocomotion.PlatformMovement + m_CharacterLocomotion.Up * m_CharacterLocomotion.ColliderSpacing, ref m_CombinedRaycastHits, ref m_ColliderIndexMap);

                    // The character hit the ground if any hit points are below the collider.
                    for (int i = 0; i < hitCount; ++i)
                    {
                        var closestRaycastHit = QuickSelect.SmallestK(m_CombinedRaycastHits, hitCount, i, m_RaycastHitComparer);

                        // The hit point has to be under the collider for the character to align to it.
                        var activeCollider = m_CharacterLocomotion.ColliderCount > 1 ? m_CharacterLocomotion.Colliders[m_ColliderIndexMap[closestRaycastHit]] : m_CharacterLocomotion.Colliders[0];
                        if (!MathUtility.IsUnderCollider(m_Transform, activeCollider, closestRaycastHit.point))
                        {
                            continue;
                        }

                        m_CharacterLocomotion.GravityDirection = -closestRaycastHit.normal;
                        updateNormalRotation = true;
                        break;
                    }
                }
            }

            // The rotation is affected by aligning to the ground or having a different up rotation from gravity.
            if (updateNormalRotation)
            {
                Rotate(targetNormal);
            }
        }
Пример #30
0
        public static Vector2 GetNormal(this Vector2 v)
        {
            var normal = Vector3.Cross(new Vector3(v.x, v.y, 0), new Vector3(0, 0, 1)).normalized;

            return(new Vector2(normal.x, normal.y));
        }
Пример #31
0
        public static void LookAt(ref Vector3 forward, ref Vector3 up, out Matrix3 result)
        {
            var Z = forward.Normalize();
            var X = up.Cross(Z).Normalize();
            var Y = Z.Cross(X);

            result.X = X;
            result.Y = Y;
            result.Z = Z;
        }
Пример #32
0
        // based on noontz's code here: http://forum.unity3d.com/threads/38984-How-to-Calculate-Mesh-Tangents
        public static void UpdateTangents(Mesh mesh)
        {
            ProfileTimer.Push("UpdateTangents");
            Vector4[] tangents      = new Vector4[mesh.vertexCount];
            int       triangleCount = mesh.triangles.Length / 3;

            Vector3[] tan1 = new Vector3[mesh.vertexCount];
            Vector3[] tan2 = new Vector3[mesh.vertexCount];
            int       tri  = 0;
            Vector3   sdir = new Vector3();
            Vector3   tdir = new Vector3();

            for (int i = 0; i < triangleCount; i++)
            {
                int i1 = mesh.triangles[tri];
                int i2 = mesh.triangles[tri + 1];
                int i3 = mesh.triangles[tri + 2];

                Vector3 v1 = mesh.vertices[i1];
                Vector3 v2 = mesh.vertices[i2];
                Vector3 v3 = mesh.vertices[i3];

                Vector2 w1 = mesh.uv[i1];
                Vector2 w2 = mesh.uv[i2];
                Vector2 w3 = mesh.uv[i3];


                float x1 = v2.x - v1.x;
                float x2 = v3.x - v1.x;
                float y1 = v2.y - v1.y;
                float y2 = v3.y - v1.y;
                float z1 = v2.z - v1.z;
                float z2 = v3.z - v1.z;

                float s1 = w2.x - w1.x;
                float s2 = w3.x - w1.x;
                float t1 = w2.y - w1.y;
                float t2 = w3.y - w1.y;

                float r = 1.0f / (s1 * t2 - s2 * t1);

                sdir.x = (t2 * x1 - t1 * x2);
                sdir.y = (t2 * y1 - t1 * y2);
                sdir.z = (t2 * z1 - t1 * z2);
                sdir  *= r;

                tdir.x = (s1 * x2 - s2 * x1);
                tdir.y = (s1 * y2 - s2 * y1);
                tdir.z = (s1 * z2 - s2 * z1);
                tdir  *= r;

                tan1[i1] += sdir;
                tan1[i2] += sdir;
                tan1[i3] += sdir;

                tan2[i1] += tdir;
                tan2[i2] += tdir;
                tan2[i3] += tdir;

                tri += 3;
            }

            for (int i = 0; i < mesh.vertexCount; i++)
            {
                Vector3 n = mesh.normals[i];
                Vector3 t = tan1[i];

                // Gram-Schmidt orthogonalize
                Vector3.OrthoNormalize(ref n, ref t);

                tangents[i].x = t.x;
                tangents[i].y = t.y;
                tangents[i].z = t.z;

                // Calculate handedness
                tangents[i].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[i]) < 0.0f) ? -1.0f : 1.0f;
            }

            mesh.tangents = tangents;
            ProfileTimer.Pop("UpdateTangents");
        }
Пример #33
0
    public void SplitMesh(Transform meshTransform, Mesh mesh, Plane plane, bool cap)
    {
        //Debug Code Start
        float startTime = Time.realtimeSinceStartup;

        //Debug Code Stop
        Vector3[] meshVertices = mesh.vertices;
        Vector2[] meshUV       = mesh.uv;
        int       newTriangles = 0;
        int       newEdges     = 0;

        for (int i = 0; i < meshVertices.Length; i += 3)
        {
            float v0 = plane.GetDistanceToPoint(meshTransform.TransformPoint(meshVertices[i]));
            float v1 = plane.GetDistanceToPoint(meshTransform.TransformPoint(meshVertices[i + 1]));
            float v2 = plane.GetDistanceToPoint(meshTransform.TransformPoint(meshVertices[i + 2]));
            v0 = Mathf.Abs(v0) > 0.001?v0:0;
            v1 = Mathf.Abs(v1) > 0.001?v1:0;
            v2 = Mathf.Abs(v2) > 0.001?v2:0;
            if (!(v0 <= 0 && v1 <= 0 && v2 <= 0))
            {
                newTriangles += 3;
                if (v0 < 0 && v1 > 0 && v2 > 0)
                {
                    newTriangles += 3;
                }
                else if (v0 > 0 && v1 < 0 && v2 > 0)
                {
                    newTriangles += 3;
                }
                else if (v0 > 0 && v1 > 0 && v2 < 0)
                {
                    newTriangles += 3;
                }
                if (!(v0 >= 0 && v1 >= 0 && v2 >= 0))
                {
                    newEdges += 2;
                }
                else if (v0 > 0 && v1 == 0 && v2 == 0)
                {
                    newEdges += 2;
                }
                else if (v0 == 0 && v1 > 0 && v2 == 0)
                {
                    newEdges += 2;
                }
                else if (v0 == 0 && v1 == 0 && v2 > 0)
                {
                    newEdges += 2;
                }
            }
        }
        Vector3[] vertices  = new Vector3[newTriangles + newEdges * 3 / 2];
        Vector2[] uv        = new Vector2[newTriangles + newEdges * 3 / 2];
        int[]     triangles = new int[newTriangles + newEdges * 3 / 2];
        int[]     edges     = new int[newEdges];
        for (int i = 0, j = 0, k = 0; i < meshVertices.Length; i += 3)
        {
            float v0 = plane.GetDistanceToPoint(meshTransform.TransformPoint(meshVertices[i]));
            float v1 = plane.GetDistanceToPoint(meshTransform.TransformPoint(meshVertices[i + 1]));
            float v2 = plane.GetDistanceToPoint(meshTransform.TransformPoint(meshVertices[i + 2]));
            v0 = Mathf.Abs(v0) > 0.001?v0:0;
            v1 = Mathf.Abs(v1) > 0.001?v1:0;
            v2 = Mathf.Abs(v2) > 0.001?v2:0;
            if (!(v0 <= 0 && v1 <= 0 && v2 <= 0))
            {
                if (v0 >= 0 && v1 >= 0 && v2 >= 0)
                {
                    vertices[j]      = meshVertices[i];
                    vertices[j + 1]  = meshVertices[i + 1];
                    vertices[j + 2]  = meshVertices[i + 2];
                    uv[j]            = meshUV[i];
                    uv[j + 1]        = meshUV[i + 1];
                    uv[j + 2]        = meshUV[i + 2];
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    if (v0 > 0 && v1 == 0 && v2 == 0)
                    {
                        edges[k]     = j + 1;
                        edges[k + 1] = j + 2;
                        k           += 2;
                    }
                    else if (v0 == 0 && v1 > 0 && v2 == 0)
                    {
                        edges[k]     = j;
                        edges[k + 1] = j + 2;
                        k           += 2;
                    }
                    else if (v0 == 0 && v1 == 0 && v2 > 0)
                    {
                        edges[k]     = j;
                        edges[k + 1] = j + 1;
                        k           += 2;
                    }
                    j += 3;
                }
                else if (v0 > 0 && v1 < 0 && v2 < 0)
                {
                    vertices[j]      = meshVertices[i];
                    vertices[j + 1]  = meshVertices[i + 1] + (meshVertices[i] - meshVertices[i + 1]) * (1 - v0 / (v0 - v1));
                    vertices[j + 2]  = meshVertices[i + 2] + (meshVertices[i] - meshVertices[i + 2]) * (1 - v0 / (v0 - v2));
                    uv[j]            = meshUV[i];
                    uv[j + 1]        = meshUV[i + 1] + (meshUV[i] - meshUV[i + 1]) * (1 - v0 / (v0 - v1));
                    uv[j + 2]        = meshUV[i + 2] + (meshUV[i] - meshUV[i + 2]) * (1 - v0 / (v0 - v2));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j + 1;
                    edges[k + 1]     = j + 2;
                    k += 2;
                    j += 3;
                }
                else if (v0 < 0 && v1 > 0 && v2 < 0)
                {
                    vertices[j]      = meshVertices[i] + (meshVertices[i + 1] - meshVertices[i]) * (1 - v1 / (v1 - v0));
                    vertices[j + 1]  = meshVertices[i + 1];
                    vertices[j + 2]  = meshVertices[i + 2] + (meshVertices[i + 1] - meshVertices[i + 2]) * (1 - v1 / (v1 - v2));
                    uv[j]            = meshUV[i] + (meshUV[i + 1] - meshUV[i]) * (1 - v1 / (v1 - v0));
                    uv[j + 1]        = meshUV[i + 1];
                    uv[j + 2]        = meshUV[i + 2] + (meshUV[i + 1] - meshUV[i + 2]) * (1 - v1 / (v1 - v2));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j;
                    edges[k + 1]     = j + 2;
                    k += 2;
                    j += 3;
                }
                else if (v0 < 0 && v1 < 0 && v2 > 0)
                {
                    vertices[j]      = meshVertices[i] + (meshVertices[i + 2] - meshVertices[i]) * (1 - v2 / (v2 - v0));
                    vertices[j + 1]  = meshVertices[i + 1] + (meshVertices[i + 2] - meshVertices[i + 1]) * (1 - v2 / (v2 - v1));
                    vertices[j + 2]  = meshVertices[i + 2];
                    uv[j]            = meshUV[i] + (meshUV[i + 2] - meshUV[i]) * (1 - v2 / (v2 - v0));
                    uv[j + 1]        = meshUV[i + 1] + (meshUV[i + 2] - meshUV[i + 1]) * (1 - v2 / (v2 - v1));
                    uv[j + 2]        = meshUV[i + 2];
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j;
                    edges[k + 1]     = j + 1;
                    k += 2;
                    j += 3;
                }
                else if (v0 > 0 && v1 <= 0 && v2 < 0)
                {
                    vertices[j]      = meshVertices[i];
                    vertices[j + 1]  = meshVertices[i + 1] + (meshVertices[i] - meshVertices[i + 1]) * (1 - v0 / (v0 - v1));
                    vertices[j + 2]  = meshVertices[i + 2] + (meshVertices[i] - meshVertices[i + 2]) * (1 - v0 / (v0 - v2));
                    uv[j]            = meshUV[i];
                    uv[j + 1]        = meshUV[i + 1] + (meshUV[i] - meshUV[i + 1]) * (1 - v0 / (v0 - v1));
                    uv[j + 2]        = meshUV[i + 2] + (meshUV[i] - meshUV[i + 2]) * (1 - v0 / (v0 - v2));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j + 1;
                    edges[k + 1]     = j + 2;
                    k += 2;
                    j += 3;
                }
                else if (v0 <= 0 && v1 > 0 && v2 < 0)
                {
                    vertices[j]      = meshVertices[i] + (meshVertices[i + 1] - meshVertices[i]) * (1 - v1 / (v1 - v0));
                    vertices[j + 1]  = meshVertices[i + 1];
                    vertices[j + 2]  = meshVertices[i + 2] + (meshVertices[i + 1] - meshVertices[i + 2]) * (1 - v1 / (v1 - v2));
                    uv[j]            = meshUV[i] + (meshUV[i + 1] - meshUV[i]) * (1 - v1 / (v1 - v0));
                    uv[j + 1]        = meshUV[i + 1];
                    uv[j + 2]        = meshUV[i + 2] + (meshUV[i + 1] - meshUV[i + 2]) * (1 - v1 / (v1 - v2));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j;
                    edges[k + 1]     = j + 2;
                    k += 2;
                    j += 3;
                }
                else if (v0 <= 0 && v1 < 0 && v2 > 0)
                {
                    vertices[j]      = meshVertices[i] + (meshVertices[i + 2] - meshVertices[i]) * (1 - v2 / (v2 - v0));
                    vertices[j + 1]  = meshVertices[i + 1] + (meshVertices[i + 2] - meshVertices[i + 1]) * (1 - v2 / (v2 - v1));
                    vertices[j + 2]  = meshVertices[i + 2];
                    uv[j]            = meshUV[i] + (meshUV[i + 2] - meshUV[i]) * (1 - v2 / (v2 - v0));
                    uv[j + 1]        = meshUV[i + 1] + (meshUV[i + 2] - meshUV[i + 1]) * (1 - v2 / (v2 - v1));
                    uv[j + 2]        = meshUV[i + 2];
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j;
                    edges[k + 1]     = j + 1;
                    k += 2;
                    j += 3;
                }
                else if (v0 > 0 && v1 < 0 && v2 <= 0)
                {
                    vertices[j]      = meshVertices[i];
                    vertices[j + 1]  = meshVertices[i + 1] + (meshVertices[i] - meshVertices[i + 1]) * (1 - v0 / (v0 - v1));
                    vertices[j + 2]  = meshVertices[i + 2] + (meshVertices[i] - meshVertices[i + 2]) * (1 - v0 / (v0 - v2));
                    uv[j]            = meshUV[i];
                    uv[j + 1]        = meshUV[i + 1] + (meshUV[i] - meshUV[i + 1]) * (1 - v0 / (v0 - v1));
                    uv[j + 2]        = meshUV[i + 2] + (meshUV[i] - meshUV[i + 2]) * (1 - v0 / (v0 - v2));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j + 1;
                    edges[k + 1]     = j + 2;
                    k += 2;
                    j += 3;
                }
                else if (v0 < 0 && v1 > 0 && v2 <= 0)
                {
                    vertices[j]      = meshVertices[i] + (meshVertices[i + 1] - meshVertices[i]) * (1 - v1 / (v1 - v0));
                    vertices[j + 1]  = meshVertices[i + 1];
                    vertices[j + 2]  = meshVertices[i + 2] + (meshVertices[i + 1] - meshVertices[i + 2]) * (1 - v1 / (v1 - v2));
                    uv[j]            = meshUV[i] + (meshUV[i + 1] - meshUV[i]) * (1 - v1 / (v1 - v0));
                    uv[j + 1]        = meshUV[i + 1];
                    uv[j + 2]        = meshUV[i + 2] + (meshUV[i + 1] - meshUV[i + 2]) * (1 - v1 / (v1 - v2));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j;
                    edges[k + 1]     = j + 2;
                    k += 2;
                    j += 3;
                }
                else if (v0 < 0 && v1 <= 0 && v2 > 0)
                {
                    vertices[j]      = meshVertices[i] + (meshVertices[i + 2] - meshVertices[i]) * (1 - v2 / (v2 - v0));
                    vertices[j + 1]  = meshVertices[i + 1] + (meshVertices[i + 2] - meshVertices[i + 1]) * (1 - v2 / (v2 - v1));
                    vertices[j + 2]  = meshVertices[i + 2];
                    uv[j]            = meshUV[i] + (meshUV[i + 2] - meshUV[i]) * (1 - v2 / (v2 - v0));
                    uv[j + 1]        = meshUV[i + 1] + (meshUV[i + 2] - meshUV[i + 1]) * (1 - v2 / (v2 - v1));
                    uv[j + 2]        = meshUV[i + 2];
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j;
                    edges[k + 1]     = j + 1;
                    k += 2;
                    j += 3;
                }
                else if (v0 < 0 && v1 > 0 && v2 > 0)
                {
                    vertices[j]      = meshVertices[i] + (meshVertices[i + 1] - meshVertices[i]) * (1 - v1 / (v1 - v0));
                    vertices[j + 1]  = meshVertices[i + 1];
                    vertices[j + 2]  = meshVertices[i + 2];
                    uv[j]            = meshUV[i] + (meshUV[i + 1] - meshUV[i]) * (1 - v1 / (v1 - v0));
                    uv[j + 1]        = meshUV[i + 1];
                    uv[j + 2]        = meshUV[i + 2];
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    j               += 3;
                    vertices[j]      = meshVertices[i] + (meshVertices[i + 1] - meshVertices[i]) * (1 - v1 / (v1 - v0));
                    vertices[j + 1]  = meshVertices[i + 2];
                    vertices[j + 2]  = meshVertices[i] + (meshVertices[i + 2] - meshVertices[i]) * (1 - v2 / (v2 - v0));
                    uv[j]            = meshUV[i] + (meshUV[i + 1] - meshUV[i]) * (1 - v1 / (v1 - v0));
                    uv[j + 1]        = meshUV[i + 2];
                    uv[j + 2]        = meshUV[i] + (meshUV[i + 2] - meshUV[i]) * (1 - v2 / (v2 - v0));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j;
                    edges[k + 1]     = j + 2;
                    k               += 2;
                    j               += 3;
                }
                else if (v0 > 0 && v1 < 0 && v2 > 0)
                {
                    vertices[j]      = meshVertices[i];
                    vertices[j + 1]  = meshVertices[i + 1] + (meshVertices[i + 2] - meshVertices[i + 1]) * (1 - v2 / (v2 - v1));
                    vertices[j + 2]  = meshVertices[i + 2];
                    uv[j]            = meshUV[i];
                    uv[j + 1]        = meshUV[i + 1] + (meshUV[i + 2] - meshUV[i + 1]) * (1 - v2 / (v2 - v1));
                    uv[j + 2]        = meshUV[i + 2];
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    j               += 3;
                    vertices[j]      = meshVertices[i];
                    vertices[j + 1]  = meshVertices[i + 1] + (meshVertices[i] - meshVertices[i + 1]) * (1 - v0 / (v0 - v1));
                    vertices[j + 2]  = meshVertices[i + 1] + (meshVertices[i + 2] - meshVertices[i + 1]) * (1 - v2 / (v2 - v1));
                    uv[j]            = meshUV[i];
                    uv[j + 1]        = meshUV[i + 1] + (meshUV[i] - meshUV[i + 1]) * (1 - v0 / (v0 - v1));
                    uv[j + 2]        = meshUV[i + 1] + (meshUV[i + 2] - meshUV[i + 1]) * (1 - v2 / (v2 - v1));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j + 1;
                    edges[k + 1]     = j + 2;
                    k               += 2;
                    j               += 3;
                }
                else if (v0 > 0 && v1 > 0 && v2 < 0)
                {
                    vertices[j]      = meshVertices[i];
                    vertices[j + 1]  = meshVertices[i + 1];
                    vertices[j + 2]  = meshVertices[i + 2] + (meshVertices[i + 1] - meshVertices[i + 2]) * (1 - v1 / (v1 - v2));
                    uv[j]            = meshUV[i];
                    uv[j + 1]        = meshUV[i + 1];
                    uv[j + 2]        = meshUV[i + 2] + (meshUV[i + 1] - meshUV[i + 2]) * (1 - v1 / (v1 - v2));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    j               += 3;
                    vertices[j]      = meshVertices[i];
                    vertices[j + 1]  = meshVertices[i + 2] + (meshVertices[i + 1] - meshVertices[i + 2]) * (1 - v1 / (v1 - v2));
                    vertices[j + 2]  = meshVertices[i + 2] + (meshVertices[i] - meshVertices[i + 2]) * (1 - v0 / (v0 - v2));
                    uv[j]            = meshUV[i];
                    uv[j + 1]        = meshUV[i + 2] + (meshUV[i + 1] - meshUV[i + 2]) * (1 - v1 / (v1 - v2));
                    uv[j + 2]        = meshUV[i + 2] + (meshUV[i] - meshUV[i + 2]) * (1 - v0 / (v0 - v2));
                    triangles[j]     = j;
                    triangles[j + 1] = j + 1;
                    triangles[j + 2] = j + 2;
                    edges[k]         = j + 1;
                    edges[k + 1]     = j + 2;
                    k               += 2;
                    j               += 3;
                }
            }
        }
        if (cap && edges.Length > 2)
        {
            Vector3 edgesAverage = Vector3.zero;
            for (int i = 0; i < edges.Length; i++)
            {
                edgesAverage += vertices[edges[i]] / newEdges;
            }
            Vector3 x        = (vertices[edges[0]] - edgesAverage).normalized;
            Vector3 y        = Vector3.Cross(plane.normal, x).normalized;
            int     maxIndex = 0;
            float   max      = 0;
            for (int i = 0; i < edges.Length; i++)
            {
                if (Vector3.Dot(vertices[edges[i]] - edgesAverage, vertices[edges[i]] - edgesAverage) > max)
                {
                    max      = Vector3.Dot(vertices[edges[i]] - edgesAverage, vertices[edges[i]] - edgesAverage);
                    maxIndex = i;
                }
            }
            max = Vector2.Distance(new Vector2(Vector3.Dot(vertices[edges[maxIndex]], x), Vector3.Dot(vertices[edges[maxIndex]], y)), Vector2.zero);
            for (int i = 0, j = newTriangles; i < edges.Length; i += 2)
            {
                if (Vector3.Dot(meshTransform.TransformDirection(Vector3.Cross(vertices[edges[i]] - edgesAverage, vertices[edges[i + 1]] - edgesAverage)), plane.normal) > 0)
                {
                    vertices[j]     = vertices[edges[i + 1]];
                    vertices[j + 1] = vertices[edges[i]];
                    vertices[j + 2] = edgesAverage;
                    uv[j]           = new Vector2(Vector3.Dot(vertices[edges[i + 1]], x), Vector3.Dot(vertices[edges[i + 1]], y)) * 0.5f / max + Vector2.one * 0.5f;
                    uv[j + 1]       = new Vector2(Vector3.Dot(vertices[edges[i]], x), Vector3.Dot(vertices[edges[i]], y)) * 0.5f / max + Vector2.one * 0.5f;
                    uv[j + 2]       = Vector2.one * 0.5f;
                }
                else
                {
                    vertices[j]     = vertices[edges[i]];
                    vertices[j + 1] = vertices[edges[i + 1]];
                    vertices[j + 2] = edgesAverage;
                    uv[j]           = new Vector2(Vector3.Dot(vertices[edges[i]], x), Vector3.Dot(vertices[edges[i]], y)) * 0.5f / max + Vector2.one * 0.5f;
                    uv[j + 1]       = new Vector2(Vector3.Dot(vertices[edges[i + 1]], x), Vector3.Dot(vertices[edges[i + 1]], y)) * 0.5f / max + Vector2.one * 0.5f;
                    uv[j + 2]       = Vector2.one * 0.5f;
                }
                triangles[j]     = j;
                triangles[j + 1] = j + 1;
                triangles[j + 2] = j + 2;
                j += 3;
            }
        }
        mesh.Clear();
        mesh.vertices  = vertices;
        mesh.uv        = uv;
        mesh.normals   = new Vector3[triangles.Length];
        mesh.triangles = triangles;
        mesh.RecalculateNormals();
        //Debug Code Start
        print("SplitMesh total execution time: " + (Time.realtimeSinceStartup - startTime) + " seconds for " + (triangles.Length / 3) + " triangles");
        //Debug Code Stop
    }
Пример #34
0
    void FixedUpdate()
    {
        // reset movement state
        m_movementState = MovementState.NONE;

        // reset movement Vector
        m_movementVector = Vector3.zero;

        // Forward
        if (Input.GetKey(SingletonManager.GameManager.m_gameControls.forward))
        {
            m_movementVector += Vector3.Normalize(Camera.main.transform.forward);
        }

        // Backward
        if (Input.GetKey(SingletonManager.GameManager.m_gameControls.backward))
        {
            m_movementVector += -Vector3.Normalize(Camera.main.transform.forward);
        }

        // Left
        if (Input.GetKey(SingletonManager.GameManager.m_gameControls.left))
        {
            Vector3 tmp = Vector3.Normalize(Camera.main.transform.forward);
            m_movementVector += Vector3.Cross(tmp, Vector3.up);
        }

        // Right
        if (Input.GetKey(SingletonManager.GameManager.m_gameControls.right))
        {
            Vector3 tmp = Vector3.Normalize(Camera.main.transform.forward);
            m_movementVector += -Vector3.Cross(tmp, Vector3.up);
        }

        // Debug.DrawLine
        // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

        // make movementVector with length of 1
        m_movementVector.Normalize();

        // Update player state
        UpdatePlayerState();



        CanUncrouch();

        if (m_movementVector != Vector3.zero)
        {
            m_movementVector     = m_movementVector * m_movementSpeed * 100.0f * Time.fixedDeltaTime;
            m_movementVector.y   = m_rigidbody.velocity.y; // this needs to be here, else the gravity on y-axis won't take effect on player while moving
            m_rigidbody.velocity = m_movementVector;
        }
        else
        {
            // player won't slide anymore
            m_rigidbody.velocity = new Vector3(0.0f, m_rigidbody.velocity.y, 0.0f);
        }

        m_crouchState = m_movementState;
    }
Пример #35
0
        public void Rotate( ref Vector3 _Axis, double _Angle, out Vector3 _Out )
        {
            double	cos_ang = Math.Cos( _Angle );
            double	sin_ang = Math.Sin( _Angle );

            _Out.x = x * cos_ang;
            _Out.y = y * cos_ang;
            _Out.z = z * cos_ang;

            double	temp = Dot( ref _Axis );
                    temp *= 1.0-cos_ang;

            _Out.x += _Axis.x * temp;
            _Out.y += _Axis.y * temp;
            _Out.z += _Axis.z * temp;

            _Axis.Cross( ref this, out TempCross );

            _Out.x += TempCross.x * sin_ang;
            _Out.y += TempCross.y * sin_ang;
            _Out.z += TempCross.z * sin_ang;
        }
Пример #36
0
    public void GenerateMesh(Simulation.TerrainCell[,] cellHeights, Simulation.TerrainManager terMan, Material MeshMaterial)
    {
        Vector3 tp = transform.position;

        int numVerts     = (cellHeights.GetLength(0) + 1) * (cellHeights.GetLength(1) + 1) * 6;
        int numTriangles = (cellHeights.GetLength(0) + 1) * (cellHeights.GetLength(1) + 1) * 6;

        Vector3[] verts     = new Vector3[numVerts];
        int[]     triangles = new int[numTriangles];
        Vector3[] normals   = new Vector3[numVerts];
        Vector2[] uv        = new Vector2[numVerts];

        int counter = 0;

        for (int i = 0; i < cellHeights.GetLength(0); i++)
        {
            for (int j = 0; j < cellHeights.GetLength(1); j++)
            {
                float cellHeight = 0;                // cellHeights[i, j].GetHeight();

                float downCell = 0, upCell = 0, rightCell = 0, leftCell = 0;
                float downRightCell = 0, downLeftCell = 0, upRightCell = 0, upLeftCell = 0;

                if (i == 0 || i == cellHeights.GetLength(0) - 1 || j == 0 || j == cellHeights.GetLength(1) - 1)
                {
                    //downCell = terMan.GetHeightAtCell(i + 1 + tp.x, j + tp.z);
                    //upCell = terMan.GetHeightAtCell(i - 1 + tp.x, j + tp.z);
                    //rightCell = terMan.GetHeightAtCell(i + tp.x, j + 1 + tp.z);
                    //leftCell = terMan.GetHeightAtCell(i + tp.x, j - 1 + tp.z);
                    //
                    //downRightCell = terMan.GetHeightAtCell(i + 1 + tp.x, j + 1 + tp.z);
                    //downLeftCell = terMan.GetHeightAtCell(i + 1 + tp.x, j - 1 + tp.z);
                    //upRightCell = terMan.GetHeightAtCell(i - 1 + tp.x, j + 1 + tp.z);
                    //upLeftCell = terMan.GetHeightAtCell(i - 1 + tp.x, j - 1 + tp.z);
                }
                else
                {
                    //downCell = cellHeights[i + 1, j].GetHeight();
                    //upCell = cellHeights[i - 1, j].GetHeight();
                    //rightCell = cellHeights[i, j + 1].GetHeight();
                    //leftCell = cellHeights[i, j - 1].GetHeight();
                    //
                    //downRightCell = cellHeights[i + 1, j + 1].GetHeight();
                    //downLeftCell = cellHeights[i + 1, j - 1].GetHeight();
                    //upRightCell = cellHeights[i - 1, j + 1].GetHeight();
                    //upLeftCell = cellHeights[i - 1, j - 1].GetHeight();
                }
                float topRightCorner    = Mathf.Max(cellHeight, downCell, rightCell, downRightCell);;
                float topLeftCorner     = Mathf.Max(cellHeight, downCell, leftCell, downLeftCell);
                float bottomRightCorner = Mathf.Max(cellHeight, upCell, rightCell, upRightCell);;
                float bottomLeftCorner  = Mathf.Max(cellHeight, upCell, leftCell, upLeftCell);;


                if (topRightCorner == bottomLeftCorner)
                {
                    verts[counter]     = new Vector3(i, bottomLeftCorner, j);
                    verts[counter + 1] = new Vector3(i, bottomRightCorner, j + 1);
                    verts[counter + 2] = new Vector3(i + 1, topRightCorner, j + 1);

                    verts[counter + 3] = new Vector3(i, bottomLeftCorner, j);
                    verts[counter + 4] = new Vector3(i + 1, topRightCorner, j + 1);
                    verts[counter + 5] = new Vector3(i + 1, topLeftCorner, j);

                    Vector3 bL = new Vector3(i, bottomLeftCorner, j);
                    Vector3 bR = new Vector3(i, bottomRightCorner, j + 1);
                    Vector3 tL = new Vector3(i + 1, topLeftCorner, j);
                    Vector3 tR = new Vector3(i + 1, topRightCorner, j + 1);

                    Vector3 upperCross = Vector3.Cross(tR - bR, bL - bR).normalized;
                    Vector3 lowerCross = Vector3.Cross(bL - tL, tR - tL).normalized;

                    normals[counter]     = normals[counter + 1] = normals[counter + 2] = upperCross;
                    normals[counter + 3] = normals[counter + 4] = normals[counter + 5] = lowerCross;

                    uv[counter]     = new Vector2(i, j);
                    uv[counter + 1] = new Vector2(i, j + 1);
                    uv[counter + 2] = new Vector2(i + 1, j + 1);

                    uv[counter + 3] = new Vector2(i, j);
                    uv[counter + 4] = new Vector2(i + 1, j + 1);
                    uv[counter + 5] = new Vector2(i + 1, j);
                }
                else
                {
                    verts[counter]     = new Vector3(i, bottomLeftCorner, j);
                    verts[counter + 1] = new Vector3(i, bottomRightCorner, j + 1);
                    verts[counter + 2] = new Vector3(i + 1, topLeftCorner, j);

                    verts[counter + 3] = new Vector3(i, bottomRightCorner, j + 1);
                    verts[counter + 4] = new Vector3(i + 1, topRightCorner, j + 1);
                    verts[counter + 5] = new Vector3(i + 1, topLeftCorner, j);

                    Vector3 bL = new Vector3(i, bottomLeftCorner, j);
                    Vector3 bR = new Vector3(i, bottomRightCorner, j + 1);
                    Vector3 tL = new Vector3(i + 1, topLeftCorner, j);
                    Vector3 tR = new Vector3(i + 1, topRightCorner, j + 1);

                    Vector3 upperCross = Vector3.Cross(tL - tR, bR - tR).normalized;
                    Vector3 lowerCross = Vector3.Cross(bR - bL, tL - bL).normalized;

                    normals[counter]     = normals[counter + 1] = normals[counter + 2] = lowerCross;
                    normals[counter + 3] = normals[counter + 4] = normals[counter + 5] = upperCross;

                    uv[counter]     = new Vector2(i, j);
                    uv[counter + 1] = new Vector2(i, j + 1);
                    uv[counter + 2] = new Vector2(i + 1, j);

                    uv[counter + 3] = new Vector2(i, j + 1);
                    uv[counter + 4] = new Vector2(i + 1, j + 1);
                    uv[counter + 5] = new Vector2(i + 1, j);
                }
                counter += 6;
            }
        }

        for (int i = 0; i < (cellHeights.GetLength(0) + 1) * (cellHeights.GetLength(1) + 1) * 6; i++)
        {
            triangles[i] = i;             //no vertex saving, each triangle gets its own three vertices, in order
        }

        mesh           = new Mesh();
        mesh.name      = "Chunk Mesh";
        mesh.vertices  = verts;
        mesh.triangles = triangles;
        mesh.normals   = normals;
        mesh.uv        = uv;

        GetComponent <MeshFilter>().mesh         = mesh;
        GetComponent <MeshRenderer>().material   = MeshMaterial;
        GetComponent <MeshCollider>().sharedMesh = mesh;


        //OptemizeMesh(mesh, MeshMaterial);
    }
Пример #37
0
        void timer_Tick(object sender, EventArgs e)
        {
            Vector3 to = _Camera._Target - _Camera._Position;
            to.Normalise();
            Vector3 up = new Vector3(0, 1, 0);
            Vector3 right = up.Cross(to);
            right.Normalise();

            Vector3 newup = to.Cross(right);
            newup.Normalise();

            right.Mul(_Velocity.x);
            to.Mul(_Velocity.z);
            newup.Mul(_Velocity.y);

//            if (!Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.RightShift))
            {
                _Camera._Position.Add(right);
                _Camera._Position.Add(to);
                _Camera._Position.Add(newup);
                _Camera._Target.Add(right);
                _Camera._Target.Add(to);
                _Camera._Target.Add(newup);
            }
  /*          else
            {
                _Camera._Position.Add(right);
                _Camera._Position.Add(newup);
            }
            */
            _WootracerOptions.UpdateGUI();
            _WootracerOptions._FocusDistance = (_Camera._Target - _Camera._Position).Magnitude();
            _Camera._FOV = _WootracerOptions._FieldOfView;
            _Camera._Spherical = _WootracerOptions._Spherical;
            _Camera._Stereographic = _WootracerOptions._Stereographic;

            _Velocity *= 0.6;

            _ImageRenderer._RampValue = 1;// _ImageRenderer._MaxValue;
            _ImageRenderer.TransferLatest(false);

            if (_Dirty || _CameraDirty || _Velocity.MagnitudeSquared() > 0.0001 && _ImageRenderer != null)
            {
                _ImageRenderer.Stop();
                if (_Dirty)
                {
                    Compile();
                }
                else
                {
                    Compile();
//                    _ImageRenderer.UpdateCamera(_Camera.CreateElement().ToString());
                }
                _ImageRenderer.Render();
            }

//            if (_Velocity.MagnitudeSquared() < 0.0001)
  //              _Timer.Stop();
        }
Пример #38
0
    // Token: 0x06008627 RID: 34343 RVA: 0x003466A0 File Offset: 0x00344AA0
    public void EyeUpdateCalc(Vector3 target, int ptnNo)
    {
        if (!this.initEnd)
        {
            if (this.targetObj != null && this.targetObj.activeSelf)
            {
                this.targetObj.SetActive(false);
            }
            return;
        }
        this.nowPtnNo = ptnNo;
        if (!EyeLookCalc.isEnabled)
        {
            if (this.targetObj != null && this.targetObj.activeSelf)
            {
                this.targetObj.SetActive(false);
            }
            return;
        }
        if (Time.deltaTime == 0f)
        {
            if (this.targetObj != null && this.targetObj.activeSelf)
            {
                this.targetObj.SetActive(false);
            }
            return;
        }
        EyeTypeState  eyeTypeState  = this.eyeTypeStates[ptnNo];
        EYE_LOOK_TYPE eye_LOOK_TYPE = this.eyeTypeStates[ptnNo].lookType;

        if (eye_LOOK_TYPE == EYE_LOOK_TYPE.NO_LOOK)
        {
            this.eyeObjs[0].eyeTransform.localRotation = this.fixAngle[0];
            this.eyeObjs[1].eyeTransform.localRotation = this.fixAngle[1];
            if (this.targetObj != null && this.targetObj.activeSelf)
            {
                this.targetObj.SetActive(false);
            }
            return;
        }
        Vector3 position  = this.rootNode.InverseTransformPoint(target);
        float   magnitude = position.magnitude;

        if (magnitude < this.eyeTypeStates[ptnNo].nearDis)
        {
            position = position.normalized * this.eyeTypeStates[ptnNo].nearDis;
            target   = this.rootNode.TransformPoint(position);
        }
        Vector3 vector = new Vector3(position.x, 0f, position.z);
        float   num    = Vector3.Dot(vector, Vector3.forward);
        float   num2   = Vector3.Angle(vector, Vector3.forward);

        vector = new Vector3(0f, position.y, position.z);
        float num3 = Vector3.Dot(vector, Vector3.forward);
        float num4 = Vector3.Angle(vector, Vector3.forward);

        if (num < 0f || num3 < 0f || num2 > this.eyeTypeStates[ptnNo].hAngleLimit || num4 > this.eyeTypeStates[ptnNo].vAngleLimit)
        {
            eye_LOOK_TYPE = EYE_LOOK_TYPE.FORWARD;
        }
        if (eye_LOOK_TYPE == EYE_LOOK_TYPE.FORWARD)
        {
            target = this.rootNode.position + this.rootNode.forward * this.eyeTypeStates[ptnNo].forntTagDis;
        }
        if (eye_LOOK_TYPE == EYE_LOOK_TYPE.CONTROL || this.eyeTypeStates[ptnNo].lookType == EYE_LOOK_TYPE.CONTROL)
        {
            if (this.targetObj != null)
            {
                if (!this.targetObj.activeSelf)
                {
                    this.targetObj.SetActive(true);
                }
                target = Vector3.MoveTowards(this.rootNode.transform.position, this.targetObj.transform.position, this.eyeTypeStates[ptnNo].forntTagDis);
                this.targetObj.transform.position = Vector3.MoveTowards(this.rootNode.transform.position, target, 0.5f);
            }
        }
        else if (this.targetObj != null)
        {
            this.targetObj.transform.position = Vector3.MoveTowards(this.rootNode.transform.position, target, 0.5f);
            if (this.targetObj.activeSelf)
            {
                this.targetObj.SetActive(false);
            }
        }
        float num5 = -1f;

        foreach (EyeObject eyeObject in this.eyeObjs)
        {
            eyeObject.eyeTransform.localRotation = eyeObject.origRotation;
            Quaternion rotation   = eyeObject.eyeTransform.parent.rotation;
            Quaternion rotation2  = Quaternion.Inverse(rotation);
            Vector3    normalized = (target - eyeObject.eyeTransform.position).normalized;
            Vector3    vector2    = rotation2 * normalized;
            float      num6       = EyeLookCalc.AngleAroundAxis(eyeObject.referenceLookDir, vector2, eyeObject.referenceUpDir);
            Vector3    axis       = Vector3.Cross(eyeObject.referenceUpDir, vector2);
            Vector3    dirA       = vector2 - Vector3.Project(vector2, eyeObject.referenceUpDir);
            float      num7       = EyeLookCalc.AngleAroundAxis(dirA, vector2, axis);
            float      f          = Mathf.Max(0f, Mathf.Abs(num6) - eyeTypeState.thresholdAngleDifference) * Mathf.Sign(num6);
            float      f2         = Mathf.Max(0f, Mathf.Abs(num7) - eyeTypeState.thresholdAngleDifference) * Mathf.Sign(num7);
            num6 = Mathf.Max(Mathf.Abs(f) * Mathf.Abs(eyeTypeState.bendingMultiplier), Mathf.Abs(num6) - eyeTypeState.maxAngleDifference) * Mathf.Sign(num6) * Mathf.Sign(eyeTypeState.bendingMultiplier);
            num7 = Mathf.Max(Mathf.Abs(f2) * Mathf.Abs(eyeTypeState.bendingMultiplier), Mathf.Abs(num7) - eyeTypeState.maxAngleDifference) * Mathf.Sign(num7) * Mathf.Sign(eyeTypeState.bendingMultiplier);
            float max = eyeTypeState.maxBendingAngle;
            float min = eyeTypeState.minBendingAngle;
            if (eyeObject.eyeLR == EYE_LR.EYE_R)
            {
                max = -eyeTypeState.minBendingAngle;
                min = -eyeTypeState.maxBendingAngle;
            }
            num6 = Mathf.Clamp(num6, min, max);
            num7 = Mathf.Clamp(num7, eyeTypeState.upBendingAngle, eyeTypeState.downBendingAngle);
            Vector3 axis2 = Vector3.Cross(eyeObject.referenceUpDir, eyeObject.referenceLookDir);
            if (eye_LOOK_TYPE == EYE_LOOK_TYPE.AWAY)
            {
                if (num5 == -1f)
                {
                    float num8  = Mathf.Lerp(-1f, 1f, Mathf.InverseLerp(-this.eyeTypeStates[this.nowPtnNo].maxBendingAngle, -this.eyeTypeStates[this.nowPtnNo].minBendingAngle, eyeObject.angleH));
                    float num9  = Mathf.Lerp(-1f, 1f, Mathf.InverseLerp(-this.eyeTypeStates[this.nowPtnNo].maxBendingAngle, -this.eyeTypeStates[this.nowPtnNo].minBendingAngle, num6));
                    float num10 = num8 - num9;
                    if (Mathf.Abs(num10) < this.sorasiRate)
                    {
                        if (num10 < 0f)
                        {
                            if (num9 < -this.sorasiRate)
                            {
                                num8 = num9 + this.sorasiRate;
                            }
                            else
                            {
                                num8 = num9 - this.sorasiRate;
                            }
                        }
                        else if (num10 > 0f)
                        {
                            if (num9 > this.sorasiRate)
                            {
                                num8 = num9 - this.sorasiRate;
                            }
                            else
                            {
                                num8 = num9 + this.sorasiRate;
                            }
                        }
                        else
                        {
                            num8 = num9 + this.sorasiRate;
                        }
                        num5 = Mathf.InverseLerp(-1f, 1f, num8);
                        num6 = Mathf.Lerp(-this.eyeTypeStates[this.nowPtnNo].maxBendingAngle, -this.eyeTypeStates[this.nowPtnNo].minBendingAngle, num5);
                    }
                    else
                    {
                        num5 = Mathf.InverseLerp(-1f, 1f, num8);
                        num6 = eyeObject.angleH;
                    }
                }
                else
                {
                    num6 = Mathf.Lerp(-this.eyeTypeStates[this.nowPtnNo].maxBendingAngle, -this.eyeTypeStates[this.nowPtnNo].minBendingAngle, num5);
                }
                num7 = -num7;
            }
            eyeObject.angleH = Mathf.Lerp(eyeObject.angleH, num6, Time.deltaTime * eyeTypeState.leapSpeed);
            eyeObject.angleV = Mathf.Lerp(eyeObject.angleV, num7, Time.deltaTime * eyeTypeState.leapSpeed);
            vector2          = Quaternion.AngleAxis(eyeObject.angleH, eyeObject.referenceUpDir) * Quaternion.AngleAxis(eyeObject.angleV, axis2) * eyeObject.referenceLookDir;
            Vector3 referenceUpDir = eyeObject.referenceUpDir;
            Vector3.OrthoNormalize(ref vector2, ref referenceUpDir);
            Vector3 forward = vector2;
            eyeObject.dirUp = Vector3.Slerp(eyeObject.dirUp, referenceUpDir, Time.deltaTime * 5f);
            Vector3.OrthoNormalize(ref forward, ref eyeObject.dirUp);
            Quaternion lhs = rotation * Quaternion.LookRotation(forward, eyeObject.dirUp) * Quaternion.Inverse(rotation * Quaternion.LookRotation(eyeObject.referenceLookDir, eyeObject.referenceUpDir));
            eyeObject.eyeTransform.rotation = lhs * eyeObject.eyeTransform.rotation;
        }
        this.targetPos   = target;
        this.fixAngle[0] = this.eyeObjs[0].eyeTransform.localRotation;
        this.fixAngle[1] = this.eyeObjs[1].eyeTransform.localRotation;
        this.AngleHRateCalc();
        this.angleVRate = this.AngleVRateCalc();
    }
Пример #39
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="quat"></param>
		/// <param name="vector"></param>
		/// <returns></returns>
		public static Vector3 operator *( Quaternion quat, Vector3 vector )
		{
			// nVidia SDK implementation
			Vector3 uv, uuv;
			var qvec = new Vector3( quat.x, quat.y, quat.z );

			uv = qvec.Cross( vector );
			uuv = qvec.Cross( uv );
			uv *= ( 2.0f*quat.w );
			uuv *= 2.0f;

			return vector + uv + uuv;

			// get the rotation matrix of the Quaternion and multiply it times the vector
			//return quat.ToRotationMatrix() * vector;
		}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="plane"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="curvature"></param>
        /// <param name="xSegments"></param>
        /// <param name="ySegments"></param>
        /// <param name="normals"></param>
        /// <param name="numberOfTexCoordSets"></param>
        /// <param name="uTiles"></param>
        /// <param name="vTiles"></param>
        /// <param name="upVector"></param>
        /// <param name="orientation"></param>
        /// <param name="vertexBufferUsage"></param>
        /// <param name="indexBufferUsage"></param>
        /// <param name="vertexShadowBuffer"></param>
        /// <param name="indexShadowBuffer"></param>
        /// <returns></returns>
        public Mesh CreateCurvedIllusionPlane(string name, Plane plane, float width, float height, float curvature, int xSegments, int ySegments, bool normals, int numberOfTexCoordSets, float uTiles, float vTiles, Vector3 upVector, Quaternion orientation, BufferUsage vertexBufferUsage, BufferUsage indexBufferUsage, bool vertexShadowBuffer, bool indexShadowBuffer)
        {
            Mesh mesh = CreateManual(name);
            SubMesh subMesh = mesh.CreateSubMesh(name + "SubMesh");

            // set up vertex data, use a single shared buffer
            mesh.SharedVertexData = new VertexData();
            VertexData vertexData = mesh.SharedVertexData;

            // set up vertex declaration
            VertexDeclaration vertexDeclaration = vertexData.vertexDeclaration;
            int currentOffset = 0;

            // always need positions
            vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            // optional normals
            if(normals) {
                vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
                currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3);
            }

            for(ushort i = 0; i < numberOfTexCoordSets; i++) {
                // assumes 2d texture coordinates
                vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, i);
                currentOffset += VertexElement.GetTypeSize(VertexElementType.Float2);
            }

            vertexData.vertexCount = (xSegments + 1) * (ySegments + 1);

            // allocate vertex buffer
            HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(vertexDeclaration.GetVertexSize(0), vertexData.vertexCount, vertexBufferUsage, vertexShadowBuffer);

            // set up the binding, one source only
            VertexBufferBinding binding = vertexData.vertexBufferBinding;
            binding.SetBinding(0, vertexBuffer);

            // work out the transform required, default orientation of plane is normal along +z, distance 0
            Matrix4 xlate, xform, rot;
            Matrix3 rot3 = Matrix3.Identity;
            xlate = rot = Matrix4.Identity;

            // determine axes
            Vector3 zAxis, yAxis, xAxis;
            zAxis = plane.Normal;
            zAxis.Normalize();
            yAxis = upVector;
            yAxis.Normalize();
            xAxis = yAxis.Cross(zAxis);
            if(xAxis.Length == 0) {
                throw new AxiomException("The up vector for a plane cannot be parallel to the planes normal.");
            }

            rot3.FromAxes(xAxis, yAxis, zAxis);
            rot = rot3;

            // set up standard xform from origin
            xlate.Translation = plane.Normal * -plane.D;

            // concatenate
            xform = xlate * rot;

            // generate vertex data, imagine a large sphere with the camera located near the top,
            // the lower the curvature, the larger the sphere.  use the angle from the viewer to the
            // points on the plane
            float cameraPosition;      // camera position relative to the sphere center

            // derive sphere radius (unused)
            //float sphereDistance;      // distance from the camera to the sphere along box vertex vector
            float sphereRadius;

            // actual values irrelevant, it's the relation between the sphere's radius and the camera's position which is important
            float SPHERE_RADIUS = 100;
            float CAMERA_DISTANCE = 5;
            sphereRadius = SPHERE_RADIUS - curvature;
            cameraPosition = sphereRadius - CAMERA_DISTANCE;

            // lock the whole buffer
            float xSpace = width / xSegments;
            float ySpace = height / ySegments;
            float halfWidth = width / 2;
            float halfHeight = height / 2;
            Vector3 vec = Vector3.Zero;
            Vector3 norm = Vector3.Zero;
            Vector3 min = Vector3.Zero;
            Vector3 max = Vector3.Zero;
            float maxSquaredLength = 0;
            bool firstTime = true;

            // generate vertex data
            GenerateCurvedIllusionPlaneVertexData(vertexBuffer, ySegments, xSegments, xSpace, halfWidth, ySpace, halfHeight, xform, firstTime, normals, orientation, cameraPosition, sphereRadius, uTiles, vTiles, numberOfTexCoordSets, ref min, ref max, ref maxSquaredLength);

            // generate face list
            subMesh.useSharedVertices = true;
            Tesselate2DMesh(subMesh, xSegments + 1, ySegments + 1, false, indexBufferUsage, indexShadowBuffer);

            // generate bounds for the mesh
            mesh.BoundingBox = new AxisAlignedBox(min, max);
            mesh.BoundingSphereRadius = MathUtil.Sqrt(maxSquaredLength);

            mesh.Load();
            mesh.Touch();

            return mesh;
        }
Пример #41
0
        /// <summary>
        ///		Gets the shortest arc quaternion to rotate this vector to the destination vector. 
        /// </summary>
        /// <remarks>
        ///		Don't call this if you think the dest vector can be close to the inverse
        ///		of this vector, since then ANY axis of rotation is ok.
        ///	</remarks>
        public Quaternion GetRotationTo(Vector3 destination)
        {
            // Based on Stan Melax's article in Game Programming Gems
            Quaternion q = new Quaternion();

            Vector3 v0 = new Vector3(this.x, this.y, this.z);
            Vector3 v1 = destination;

            // normalize both vectors
            v0.Normalize();
            v1.Normalize();

            // get the cross product of the vectors
            Vector3 c = v0.Cross(v1);

            // If the cross product approaches zero, we get unstable because ANY axis will do
            // when v0 == -v1
            float d = v0.Dot(v1);

            // If dot == 1, vectors are the same
            if (d >= 1.0f)
            {
                return Quaternion.Identity;
            }

            float s = MathUtil.Sqrt( (1+d) * 2 );
            float inverse = 1 / s;

            q.x = c.x * inverse;
            q.y = c.y * inverse;
            q.z = c.z * inverse;
            q.w = s * 0.5f;

            return q;
        }
Пример #42
0
        /// Multiply a Vector3.
        public static Vector3 operator *(Quaternion lhs, Vector3 rhs)
        {
            Vector3 qVec = new Vector3(lhs.x_, lhs.y_, lhs.z_);
            Vector3 cross1 = qVec.Cross(rhs);
            Vector3 cross2 = qVec.Cross(cross1);

            return rhs + (cross1 * lhs.w_ + cross2) * 2.0f;
        }
Пример #43
0
        /// <summary>
        /// 2つのベクトルがなす角をかえす
        /// </summary>
        /// <param name="vecA"></param>
        /// <param name="vecB"></param>
        /// <returns></returns>
        public double VecToRad(Vector3 vecA, Vector3 vecB)
        {
            vecA.Normalize();
            vecB.Normalize();

            double rad = vecA.Dot(vecB);
            if (rad > 1.0) rad = 1.0;

            double dir = (double)(Math.Asin(rad) - (Math.PI / 2.0));

            if (double.IsNaN(dir))
            {
                Debug.Write("NAn");
            }

            Vector3 resVec = vecA.Cross(vecB);
            if (resVec.z > 0) dir = -dir;

            return dir;
        }
Пример #44
0
 public Vector3 GetTorque(Vector3 thrust)
 {
     return(-Vector3.Cross(pos, thrust));
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name">Name of the plane mesh.</param>
        /// <param name="plane">Plane to use for distance and orientation of the mesh.</param>
        /// <param name="width">Width in world coordinates.</param>
        /// <param name="height">Height in world coordinates.</param>
        /// <param name="xSegments">Number of x segments for tesselation.</param>
        /// <param name="ySegments">Number of y segments for tesselation.</param>
        /// <param name="normals">If true, plane normals are created.</param>
        /// <param name="numTexCoordSets">Number of 2d texture coord sets to use.</param>
        /// <param name="uTile">Number of times the texture should be repeated in the u direction.</param>
        /// <param name="vTile">Number of times the texture should be repeated in the v direction.</param>
        /// <param name="upVec">The up direction of the plane.</param>
        /// <returns></returns>
        public Mesh CreatePlane(string name, Plane plane, float width, float height, int xSegments, int ySegments, bool normals, int numTexCoordSets, float uTile, float vTile, Vector3 upVec,
            BufferUsage vertexBufferUsage, BufferUsage indexBufferUsage, bool vertexShadowBuffer, bool indexShadowBuffer )
        {
            Mesh mesh = CreateManual(name);
            SubMesh subMesh = mesh.CreateSubMesh(name + "SubMesh");

            mesh.SharedVertexData = new VertexData();
            VertexData vertexData = mesh.SharedVertexData;

            VertexDeclaration decl = vertexData.vertexDeclaration;
            int currOffset = 0;

            // add position data
            decl.AddElement(0, currOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            currOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            // normals are optional
            if(normals) {
                decl.AddElement(0, currOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
                currOffset += VertexElement.GetTypeSize(VertexElementType.Float3);
            }

            // add texture coords
            for(ushort i = 0; i < numTexCoordSets; i++) {
                decl.AddElement(0, currOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, i);
                currOffset += VertexElement.GetTypeSize(VertexElementType.Float2);
            }

            vertexData.vertexCount = (xSegments + 1) * (ySegments + 1);

            // create a new vertex buffer (based on current API)
            HardwareVertexBuffer vbuf =
                HardwareBufferManager.Instance.CreateVertexBuffer(decl.GetVertexSize(0), vertexData.vertexCount, vertexBufferUsage, vertexShadowBuffer);

            // get a reference to the vertex buffer binding
            VertexBufferBinding binding = vertexData.vertexBufferBinding;

            // bind the first vertex buffer
            binding.SetBinding(0, vbuf);

            // transform the plane based on its plane def
            Matrix4 translate = Matrix4.Identity;
            Matrix4 transform = Matrix4.Zero;
            Matrix4 rotation = Matrix4.Identity;
            Matrix3 rot3x3 = Matrix3.Zero;

            Vector3 xAxis, yAxis, zAxis;
            zAxis = plane.Normal;
            zAxis.Normalize();
            yAxis = upVec;
            yAxis.Normalize();
            xAxis = yAxis.Cross(zAxis);

            if (xAxis.Length == 0) {
                throw new AxiomException("The up vector for a plane cannot be parallel to the planes normal.");
            }

            rot3x3.FromAxes(xAxis, yAxis, zAxis);
            rotation = rot3x3;

            // set up transform from origin
            translate.Translation = plane.Normal * -plane.D;

            transform = translate * rotation;

            float xSpace = width / xSegments;
            float ySpace = height / ySegments;
            float halfWidth = width / 2;
            float halfHeight = height / 2;
            float xTexCoord = (1.0f * uTile) / xSegments;
            float yTexCoord = (1.0f * vTile) / ySegments;
            Vector3 vec = Vector3.Zero;
            Vector3 min = Vector3.Zero;
            Vector3 max = Vector3.Zero;
            float maxSquaredLength = 0;
            bool firstTime = true;

            // generate vertex data
            GeneratePlaneVertexData(vbuf, ySegments, xSegments, xSpace, halfWidth, ySpace, halfHeight, transform, firstTime, normals, rotation, numTexCoordSets, xTexCoord, yTexCoord, subMesh, ref min, ref max, ref maxSquaredLength);

            // generate face list
            Tesselate2DMesh(subMesh, xSegments + 1, ySegments + 1, false, indexBufferUsage, indexShadowBuffer);

            // generate bounds for the mesh
            mesh.BoundingBox = new AxisAlignedBox(min, max);
            mesh.BoundingSphereRadius = MathUtil.Sqrt(maxSquaredLength);

            mesh.Load();
            mesh.Touch();

            return mesh;
        }
Пример #46
0
        /// <summary>
        /// Draws all the particles in a cloud. The cloud system must be initialized, and its projection matrix must be set
        /// before this is called.
        /// The texture used to draw the particles is specified by cloud.Texture.
        /// </summary>
        /// <param name="cloud">The particle cloud to render.</param>
        /// <param name="world">The world matrix, indicating the position, rotation, and scale of the particle cloud.</param>
        /// <param name="view">The view matrix, indicating the camera's current point of view.</param>
        public void DrawParticleCloud(ParticleCloud cloud, Matrix world, Matrix view)
        {
            // Verify that we have been properly initialized.
            Debug.Assert(isInitialized, "ParticleCloudSystem has not been initialized. "
                         + "You must call Initialize() before it can draw anything.");
            Debug.Assert(isProjectionMatrixSet, "ParticleCloudSystem has not been given a projection matrix. "
                         + "You must write to Projection before it can draw anything.");

            // Remember if ZWrite was enabled.
            bool wasZWriteEnabled = device.RenderState.DepthBufferWriteEnable;

            // Get the number of particles to draw
            int numParticles = cloud.NumberOfParticles;

            // If there is nothing to draw, just skip right now.
            if (numParticles == 0)
            {
                return;
            }

            // How many render calls must be use to draw these particles?
            int numRenders = 1 + numParticles / (MaxParticlesPerRender + 1);

            // Set the correct effect technique
            if (cloud.DepthMapRendering)
            {
                particleEffect.CurrentTechnique = depthTechnique;
            }
            else
            {
                particleEffect.CurrentTechnique = cloud.SortingEnabled ? sortedTechnique : unsortedTechnique;
            }

            // Set vertex and index stuff
            device.VertexDeclaration = vertexDeclaration;
            device.Vertices[0].SetSource(vertexBuffer, 0, ParticleCloudVertex.SizeInBytes);
            device.Indices = indexBuffer;

            // Assign shader uniforms
            if (obsoleteProjection)
            {
                projectionParam.SetValue(projection);
                obsoleteProjection = false;
            }
            Matrix worldView = world * view;

            worldParam.SetValue(world);
            worldViewParam.SetValue(worldView);
            textureParam.SetValue(cloud.Texture);

            Vector3 right = Vector3.Right;
            Vector3 up    = Vector3.Up;

            // Are the particle billboards axis-aligned?
            if (cloud.AxisEnabled)
            {
                // Get the forward vector from the view matrix. Remember that the view matrix's rotation is
                // inverted, so we cannot use view.Forward.
                Vector3 forward = new Vector3(view.M13, view.M23, view.M33);

                right = Vector3.Cross(forward, cloud.Axis);
                right.Normalize();
                up = cloud.Axis;

                Vector3.TransformNormal(ref right, ref view, out right);
                Vector3.TransformNormal(ref up, ref view, out up);
            }

            // Scale the right and up vectors according to the X-scale of the WorldView matrix
            // Billboards cannot be scaled non-uniformly, so we have to assume that it is a uniform scale
            float sizeScale = worldView.Right.Length();

            right = right * sizeScale;
            up    = up * sizeScale;

            // Sends the vectors to the shader
            billboardRightParam.SetValue(right);
            billboardUpParam.SetValue(up);


            // Start rendering the particles
            particleEffect.Begin();
            for (int i = 0; i < particleEffect.CurrentTechnique.Passes.Count; i++)
            {
                EffectPass pass = particleEffect.CurrentTechnique.Passes[i];

                for (int renderN = 0; renderN < numRenders; renderN++)
                {
                    // Calculate the number of particles to render in this render call
                    int numParticlesToRender = numParticles - renderN * MaxParticlesPerRender;
                    if (numParticlesToRender > MaxParticlesPerRender)
                    {
                        numParticlesToRender = MaxParticlesPerRender;
                    }

                    // Get the array start and end indices
                    int arrayStart = renderN * MaxParticlesPerRender;
                    int arrayEnd   = arrayStart + numParticlesToRender - 1;

                    // Assign the parameters accordingly
                    if (renderN == 0)
                    {
                        // The first render pass can use the arrays directly. No need to waste time setting up the buffers.
                        positionsParam.SetValue(cloud.Positions);
                        colorsParam.SetValue(cloud.Colors);
                        orientationsParam.SetValue(cloud.Orientations);
                    }
                    else
                    {
                        // We need to construct a new array where the next 80 particles are first in the array.
                        PrepareParticleBuffers(cloud, renderN);
                        positionsParam.SetValue(positionBuffer);
                        colorsParam.SetValue(colorBuffer);
                        orientationsParam.SetValue(orientationBuffer);
                    }

                    pass.Begin();
                    device.DrawIndexedPrimitives(
                        PrimitiveType.TriangleList,
                        0,
                        0,
                        4 * numParticlesToRender,
                        0,
                        2 * numParticlesToRender);
                    pass.End();
                }
            }
            particleEffect.End();

            // It seems that ZWriteEnable propagates to other drawing calls in XNA, so we better clean up
            // after ourselves.
            if (cloud.SortingEnabled && wasZWriteEnabled)
            {
                device.RenderState.DepthBufferWriteEnable = true;
            }
        }
Пример #47
0
    private void walkingUpdate(bool didHit, RaycastHit hit, Vector3 position)
    {
        if (didHit)
        {
            var legExtensionTimingModifier = walkingLegExtensionTimingModifier;
            var stepPace = walkingStepPace;
            if (currentAnimationState == AnimationState.Running)
            {
                stepPace = runningStepPace;
                legExtensionTimingModifier = runningLegExtensionTimingModifier;
            }
            currentStepTime += Time.deltaTime;
            bool extendLeg = false;
            if (currentStepTime > stepPace)
            {
                currentStepTime = 0.0f;
                stepWithLeftLeg = !stepWithLeftLeg;
                extendLeg       = false;
            }
            else if (currentStepTime > stepPace * legExtensionTimingModifier)
            {
                extendLeg = true;
            }

            Vector3 forwardRotationVector = Vector3.Cross(forwardFacingTargetVector, Vector3.up);

            if (stepWithLeftLeg)
            {
                //Step forward With left leg
                leftThigh.AddRelativeTorque(Vector3.right * legStrength);

                //If on forward up swing of leg, bend the knee, otherwise we relax it to extend the leg and finish the forward step
                if (!extendLeg)
                {
                    leftKnee.AddRelativeTorque(-Vector3.right * legStrength * 0.5f);
                }
                //Contract foot inward
                leftFoot.AddRelativeTorque(Vector3.right * legStrength * 0.25f);


                //extend and swing leg back
                rightThigh.AddRelativeTorque(-Vector3.right * legStrength * legBackSwingModifier);
                //keep knee extended out
                rightKnee.AddRelativeTorque(Vector3.right * legStrength * legBackSwingModifier);
                //Extend foot out
                rightFoot.AddRelativeTorque(-Vector3.right * legStrength * legBackSwingModifier);

                //Swing opposite Arm forward
                rightArm.AddRelativeTorque(-Vector3.forward * armAnimStrength);
                rightForeArm.AddRelativeTorque(-Vector3.forward * armAnimStrength * 2f);
                rightForeArm.AddForce(Vector3.up * armAnimStrength);
            }
            else
            {
                //Step With right leg
                rightThigh.AddRelativeTorque(Vector3.right * legStrength);

                //If on forward up swing of leg, bend the knee, otherwise we relax it to extend the leg and finish the forward step
                if (!extendLeg)
                {
                    rightKnee.AddRelativeTorque(-Vector3.right * legStrength * 0.5f);
                }
                //Contract foot inward
                rightFoot.AddRelativeTorque(Vector3.right * legStrength * 0.25f);


                //extend and swing leg back
                leftThigh.AddRelativeTorque(-Vector3.right * legStrength * legBackSwingModifier);
                //keep knee extended out
                leftKnee.AddRelativeTorque(Vector3.right * legStrength * legBackSwingModifier);
                //Extend foot out
                leftFoot.AddRelativeTorque(-Vector3.right * legStrength * legBackSwingModifier);

                //Swing opposite Arm forward
                leftArm.AddRelativeTorque(-Vector3.forward * armAnimStrength);
                leftForeArm.AddRelativeTorque(-Vector3.forward * armAnimStrength * 2f);
                leftForeArm.AddForce(Vector3.up * armAnimStrength);
            }

            Debug.Log(leftFoot.velocity);
            Debug.Log(rightFoot.velocity);
            if (leftFoot.velocity == Vector3.zero || rightFoot.velocity == Vector3.zero)
            {
                Debug.Log("Step UP!");
                hips.AddForce(Vector3.up * footStepUpwardForceStrength);
            }
        }
    }
Пример #48
0
		/// <summary>
		///		Generates billboard corners.
		///	 </summary>
		/// <remarks>Billboard param only required for type OrientedSelf</remarks>
		protected virtual void GenerateBillboardAxes( ref Vector3 x, ref Vector3 y, Billboard bb )
		{
			// If we're using accurate facing, recalculate camera direction per BB
			if ( this.accurateFacing &&
				 ( this.billboardType == BillboardType.Point ||
				   this.billboardType == BillboardType.OrientedCommon ||
				   this.billboardType == BillboardType.OrientedSelf ) )
			{
				// cam -> bb direction
				this.camDir = bb.Position - this.camPos;
				this.camDir.Normalize();
			}

			switch ( this.billboardType )
			{
				case BillboardType.Point:
					if ( this.accurateFacing )
					{
						// Point billboards will have 'up' based on but not equal to cameras
						y = this.camQ * Vector3.UnitY;
						x = this.camDir.Cross( y );
						x.Normalize();
						y = x.Cross( this.camDir ); // both normalised already
					}
					else
					{
						// Get camera axes for X and Y (depth is irrelevant)
						x = this.camQ * Vector3.UnitX;
						y = this.camQ * Vector3.UnitY;
					}
					break;

				case BillboardType.OrientedCommon:
					// Y-axis is common direction
					// X-axis is cross with camera direction
					y = this.commonDirection;
					x = this.camDir.Cross( y );
					x.Normalize();
					break;

				case BillboardType.OrientedSelf:
					// Y-axis is direction
					// X-axis is cross with camera direction
					// Scale direction first
					y = bb.Direction;
					x = this.camDir.Cross( y );
					x.Normalize();
					break;

				case BillboardType.PerpendicularCommon:
					// X-axis is up-vector cross common direction
					// Y-axis is common direction cross X-axis
					x = this.commonUpVector.Cross( this.commonDirection );
					y = this.commonDirection.Cross( x );
					break;

				case BillboardType.PerpendicularSelf:
					// X-axis is up-vector cross own direction
					// Y-axis is own direction cross X-axis
					x = this.commonUpVector.Cross( bb.Direction );
					x.Normalize();
					y = bb.Direction.Cross( x ); // both should be normalised
					break;
			}

#if NOT
		// Default behavior is that billboards are in local node space
		// so orientation of camera (in world space) must be reverse-transformed
		// into node space to generate the axes
			Quaternion invTransform = parentNode.DerivedOrientation.Inverse();
			Quaternion camQ = Quaternion.Zero;

			switch (billboardType) {
				case BillboardType.Point:
					// Get camera world axes for X and Y (depth is irrelevant)
					camQ = camera.DerivedOrientation;
						// Convert into billboard local space
						camQ = invTransform * camQ;
					x = camQ * Vector3.UnitX;
					y = camQ * Vector3.UnitY;
					break;
				case BillboardType.OrientedCommon:
					// Y-axis is common direction
					// X-axis is cross with camera direction
					y = commonDirection;
					y.Normalize();
						// Convert into billboard local space
						camQ = invTransform * camQ;
					x = camQ * camera.DerivedDirection.Cross(y);
					x.Normalize();
					break;
				case BillboardType.OrientedSelf:
					// Y-axis is direction
					// X-axis is cross with camera direction
					y = billboard.Direction;
						// Convert into billboard local space
						camQ = invTransform * camQ;
					x = camQ * camera.DerivedDirection.Cross(y);
					x.Normalize();
					break;
				case BillboardType.PerpendicularCommon:
					// X-axis is common direction cross common up vector
					// Y-axis is coplanar with common direction and common up vector
					x = commonDirection.Cross(commonUpVector);
					x.Normalize();
					y = x.Cross(commonDirection);
					y.Normalize();
					break;
				case BillboardType.PerpendicularSelf:
					// X-axis is direction cross common up vector
					// Y-axis is coplanar with direction and common up vector
					x = billboard.Direction.Cross(commonUpVector);
					x.Normalize();
					y = x.Cross(billboard.Direction);
					y.Normalize();
					break;
			}
#endif
		}
Пример #49
0
        public void Calculate_cross_product()
        {
            var firstOperand = new Vector3(1, 5, 6);
            var secondOperand = new Vector3(4, 9, 1);

            var actual = firstOperand.Cross(secondOperand);
            Assert.AreEqual(actual.X, -49);
            Assert.AreEqual(actual.Y, 23);
            Assert.AreEqual(actual.Z, -11);
        }
 private static bool Orthogonal( Vector3 v1, Vector3 v2 )
 {
     return v1.Cross( v2 ).Length < geometryEpsilon;
 }
Пример #51
0
        public virtual bool HitTest(RenderContext context, Matrix modelMatrix, ref Ray rayWS, ref List <HitTestResult> hits, object originalSource)
        {
            if (Positions == null || Positions.Count == 0 ||
                Indices == null || Indices.Count == 0)
            {
                return(false);
            }
            bool isHit = false;

            if (Octree != null)
            {
                isHit = Octree.HitTest(context, originalSource, this, modelMatrix, rayWS, ref hits);
            }
            else
            {
                var result = new HitTestResult
                {
                    Distance = double.MaxValue
                };
                var modelInvert = modelMatrix.Inverted();
                if (modelInvert == Matrix.Zero)//Check if model matrix can be inverted.
                {
                    return(false);
                }
                //transform ray into model coordinates
                var rayModel = new Ray(Vector3.TransformCoordinate(rayWS.Position, modelInvert), Vector3.TransformNormal(rayWS.Direction, modelInvert));

                var b = this.Bound;
                //Do hit test in local space
                if (rayModel.Intersects(ref b))
                {
                    int index = 0;
                    foreach (var t in Triangles)
                    {
                        var v0 = t.P0;
                        var v1 = t.P1;
                        var v2 = t.P2;
                        if (Collision.RayIntersectsTriangle(ref rayModel, ref v0, ref v1, ref v2, out float d))
                        {
                            if (d > 0 && d < result.Distance) // If d is NaN, the condition is false.
                            {
                                result.IsValid  = true;
                                result.ModelHit = originalSource;
                                // transform hit-info to world space now:
                                var pointWorld = Vector3.TransformCoordinate(rayModel.Position + (rayModel.Direction * d), modelMatrix);
                                result.PointHit = pointWorld;
                                result.Distance = (rayWS.Position - pointWorld).Length();
                                var p0 = Vector3.TransformCoordinate(v0, modelMatrix);
                                var p1 = Vector3.TransformCoordinate(v1, modelMatrix);
                                var p2 = Vector3.TransformCoordinate(v2, modelMatrix);
                                var n  = Vector3.Cross(p1 - p0, p2 - p0);
                                n.Normalize();
                                // transform hit-info to world space now:
                                result.NormalAtHit     = n;// Vector3.TransformNormal(n, m).ToVector3D();
                                result.TriangleIndices = new System.Tuple <int, int, int>(Indices[index], Indices[index + 1], Indices[index + 2]);
                                result.Tag             = index / 3;
                                result.Geometry        = this;
                                isHit = true;
                            }
                        }
                        index += 3;
                    }
                }
                if (isHit)
                {
                    hits.Add(result);
                }
            }
            return(isHit);
        }
Пример #52
0
    Vector3 right(Vector3 v1, Vector3 v2)
    {
        Vector3 first = (v2 - v1).normalized;

        return(roadWidth * Vector3.Cross(Vector3.down, first));
    }
Пример #53
0
 public float AngleSigned(Vector3 v1, Vector3 v2, Vector3 n)//return the angle between two vectors
 {
     return(Mathf.Atan2(
                Vector3.Dot(n, Vector3.Cross(v1, v2)),
                Vector3.Dot(v1, v2)) * Mathf.Rad2Deg);
 }
Пример #54
0
        public void Align(Vector3 v1, Vector3 v2)
        {
            // If V1 and V2 are not parallel, the axis of rotation is the unit-length
            // vector U = Cross(V1,V2)/Length(Cross(V1,V2)).  The angle of rotation,
            // A, is the angle between V1 and V2.  The quaternion for the rotation is
            // q = cos(A/2) + sin(A/2)*(ux*i+uy*j+uz*k) where U = (ux,uy,uz).
            //
            // (1) Rather than extract A = acos(Dot(V1,V2)), multiply by 1/2, then
            //	 compute sin(A/2) and cos(A/2), we reduce the computational costs by
            //	 computing the bisector B = (V1+V2)/Length(V1+V2), so cos(A/2) =
            //	 Dot(V1,B).
            //
            // (2) The rotation axis is U = Cross(V1,B)/Length(Cross(V1,B)), but
            //	 Length(Cross(V1,B)) = Length(V1)*Length(B)*sin(A/2) = sin(A/2), in
            //	 which case sin(A/2)*(ux*i+uy*j+uz*k) = (cx*i+cy*j+cz*k) where
            //	 C = Cross(V1,B).
            //
            // If V1 = V2, then B = V1, cos(A/2) = 1, and U = (0,0,0).  If V1 = -V2,
            // then B = 0.  This can happen even if V1 is approximately -V2 using
            // floating point arithmetic, since Vector3::Normalize checks for
            // closeness to zero and returns the zero vector accordingly.  The test
            // for exactly zero is usually not recommend for floating point
            // arithmetic, but the implementation of Vector3::Normalize guarantees
            // the comparison is robust.  In this case, the A = pi and any axis
            // perpendicular to V1 may be used as the rotation axis.

            var bisector = v1.Add(v2);
            bisector.Normalise();

            var cosHalfAngle = v1.Dot(bisector);
            Vector3 cross;

            tuple[0] = cosHalfAngle;

            if (cosHalfAngle != 0)
            {
                cross = v1.Cross(bisector);
                tuple[1] = cross.tuple[0];
                tuple[2] = cross.tuple[1];
                tuple[3] = cross.tuple[2];
            }
            else
            {
                double invLength;
                if (System.Math.Abs(v1.tuple[0]) >= System.Math.Abs(v1.tuple[1]))
                {
                    // V1.x or V1.z is the largest magnitude component
                    invLength = 1 / System.Math.Sqrt(v1.tuple[0] * v1.tuple[0]
                                            + v1.tuple[2] * v1.tuple[2]);
                    tuple[1] = - v1.tuple[2] * invLength;
                    tuple[2] = 0;
                    tuple[3] = + v1.tuple[0] * invLength;
                }
                else
                {
                    // V1.y or V1.z is the largest magnitude component
                    invLength = 1 / System.Math.Sqrt(v1.tuple[1] * v1.tuple[1]
                                            + v1.tuple[2] * v1.tuple[2]);
                    tuple[1] = 0;
                    tuple[2] = + v1.tuple[2] * invLength;
                    tuple[3] = - v1.tuple[1] * invLength;
                }
            }
        }