Exemple #1
0
    public void Solve()
    {
        if (this.upperArm == null || this.forearm == null || this.hand == null || this.elbow == null || this.target == null)
        {
            return;
        }
        if (!Application.isPlaying && this.debug)
        {
            this.upperArm.localRotation = Quaternion.identity;
            this.forearm.localRotation  = Quaternion.identity;
            this.hand.localRotation     = Quaternion.identity;
        }
        float d = 1f;

        if (this.RightSide)
        {
            d = -1f;
        }
        Vector3 forward = Vector3.Lerp(this.upperArm.up * d, this.target.position - this.upperArm.position, this.BlendOn);
        Vector3 upwards = Vector3.Lerp(this.upperArm.forward * d, this.elbow.position - this.upperArm.position, this.BlendOn);

        this.upperArm.rotation = Quaternion.LookRotation(forward, upwards);
        this.upperArm.Rotate(this.uppperArm_OffsetRotation);
        Vector3 b = Vector3.Cross(this.elbow.position - this.upperArm.position, this.forearm.position - this.upperArm.position);

        this.upperArm_Length = Vector3.Distance(this.upperArm.position, this.forearm.position);
        this.forearm_Length  = Vector3.Distance(this.forearm.position, this.hand.position);
        this.arm_Length      = this.upperArm_Length + this.forearm_Length;
        this.targetDistance  = Vector3.Distance(this.upperArm.position, this.target.position);
        this.targetDistance  = Mathf.Min(this.targetDistance, this.arm_Length - this.arm_Length * 0.001f);
        this.adyacent        = (this.upperArm_Length * this.upperArm_Length - this.forearm_Length * this.forearm_Length + this.targetDistance * this.targetDistance) / (2f * this.targetDistance);
        this.angle           = Mathf.Acos(Mathf.Clamp(this.adyacent / this.upperArm_Length, -1f, 1f)) * 57.29578f;
        Vector3 axis = Vector3.Lerp(this.forearm.position - this.upperArm.position, b, this.BlendOn);

        this.upperArm.RotateAround(this.upperArm.position, axis, -this.angle * this.BlendOn);
        if (this.debug)
        {
            Debug.DrawRay(this.forearm.position, this.forearm.up * d, Color.blue);
            Debug.DrawRay(this.forearm.position, -this.forearm.right, Color.green);
        }
        Vector3 forward2 = Vector3.Lerp(this.forearm.up * d, this.target.position - this.forearm.position, this.BlendOn);
        Vector3 upwards2 = Vector3.Lerp(-this.forearm.right, b, this.BlendOn);

        this.forearm.rotation = Quaternion.LookRotation(forward2, upwards2);
        this.forearm.Rotate(this.forearm_OffsetRotation);
        if (this.handMatchesTargetRotation)
        {
            Quaternion rotation = Quaternion.Lerp(this.hand.rotation, this.target.rotation, this.BlendOn);
            this.hand.rotation = rotation;
            this.hand.Rotate(this.hand_OffsetRotation * this.BlendOn);
            if (this.applyHandRotationLimits)
            {
                this.ApplyRotationLimits();
            }
        }
        if (this.handMatchesTargetTransform)
        {
            this.hand.position = this.target.position;
        }
        if (this.debug)
        {
            this.debugForearmEuler = this.forearm.localEulerAngles;
            this.debugForearmQuat  = this.forearm.rotation;
            if (!(this.forearm != null) || this.elbow != null)
            {
            }
            if (!(this.upperArm != null) || this.target != null)
            {
            }
        }
    }
Exemple #2
0
    public static Mesh GenerateIcoSphereMesh(int recursionLevel, float radius)
    {
        Mesh mesh = new Mesh();

        List <Vector3>         vertList = new List <Vector3>();
        Dictionary <long, int> middlePointIndexCache = new Dictionary <long, int>();

        // create 12 vertices of a icosahedron
        float t = (1f + Mathf.Sqrt(5f)) / 2f;

        vertList.Add(new Vector3(-1f, t, 0f).normalized *radius);
        vertList.Add(new Vector3(1f, t, 0f).normalized *radius);
        vertList.Add(new Vector3(-1f, -t, 0f).normalized *radius);
        vertList.Add(new Vector3(1f, -t, 0f).normalized *radius);

        vertList.Add(new Vector3(0f, -1f, t).normalized *radius);
        vertList.Add(new Vector3(0f, 1f, t).normalized *radius);
        vertList.Add(new Vector3(0f, -1f, -t).normalized *radius);
        vertList.Add(new Vector3(0f, 1f, -t).normalized *radius);

        vertList.Add(new Vector3(t, 0f, -1f).normalized *radius);
        vertList.Add(new Vector3(t, 0f, 1f).normalized *radius);
        vertList.Add(new Vector3(-t, 0f, -1f).normalized *radius);
        vertList.Add(new Vector3(-t, 0f, 1f).normalized *radius);


        // create 20 triangles of the icosahedron
        List <TriangleIndices> faces = new List <TriangleIndices>();

        // 5 faces around point 0
        faces.Add(new TriangleIndices(0, 11, 5));
        faces.Add(new TriangleIndices(0, 5, 1));
        faces.Add(new TriangleIndices(0, 1, 7));
        faces.Add(new TriangleIndices(0, 7, 10));
        faces.Add(new TriangleIndices(0, 10, 11));

        // 5 adjacent faces
        faces.Add(new TriangleIndices(1, 5, 9));
        faces.Add(new TriangleIndices(5, 11, 4));
        faces.Add(new TriangleIndices(11, 10, 2));
        faces.Add(new TriangleIndices(10, 7, 6));
        faces.Add(new TriangleIndices(7, 1, 8));

        // 5 faces around point 3
        faces.Add(new TriangleIndices(3, 9, 4));
        faces.Add(new TriangleIndices(3, 4, 2));
        faces.Add(new TriangleIndices(3, 2, 6));
        faces.Add(new TriangleIndices(3, 6, 8));
        faces.Add(new TriangleIndices(3, 8, 9));

        // 5 adjacent faces
        faces.Add(new TriangleIndices(4, 9, 5));
        faces.Add(new TriangleIndices(2, 4, 11));
        faces.Add(new TriangleIndices(6, 2, 10));
        faces.Add(new TriangleIndices(8, 6, 7));
        faces.Add(new TriangleIndices(9, 8, 1));


        // refine triangles
        for (int i = 0; i < recursionLevel; i++)
        {
            List <TriangleIndices> faces2 = new List <TriangleIndices>();
            foreach (var tri in faces)
            {
                // replace triangle by 4 triangles
                int a = GetMiddlePoint(tri.v1, tri.v2, ref vertList, ref middlePointIndexCache, radius);
                int b = GetMiddlePoint(tri.v2, tri.v3, ref vertList, ref middlePointIndexCache, radius);
                int c = GetMiddlePoint(tri.v3, tri.v1, ref vertList, ref middlePointIndexCache, radius);

                faces2.Add(new TriangleIndices(tri.v1, a, c));
                faces2.Add(new TriangleIndices(tri.v2, b, a));
                faces2.Add(new TriangleIndices(tri.v3, c, b));
                faces2.Add(new TriangleIndices(a, b, c));
            }
            faces = faces2;
        }

        mesh.vertices = vertList.ToArray();

        List <int> triList = new List <int>();

        for (int i = 0; i < faces.Count; i++)
        {
            triList.Add(faces[i].v1);
            triList.Add(faces[i].v2);
            triList.Add(faces[i].v3);
        }
        mesh.triangles = triList.ToArray();

        var nVertices = mesh.vertices;

        Vector2[] UVs = new Vector2[nVertices.Length];

        for (var i = 0; i < nVertices.Length; i++)
        {
            var     unitVector = nVertices[i].normalized;
            Vector2 ICOuv      = new Vector2(0, 0);
            ICOuv.x = (Mathf.Atan2(unitVector.x, unitVector.z) + Mathf.PI) / Mathf.PI / 2;
            ICOuv.y = (Mathf.Acos(unitVector.y) + Mathf.PI) / Mathf.PI - 1;
            UVs[i]  = new Vector2(ICOuv.x, ICOuv.y);
        }

        mesh.uv = UVs;

        Vector3[] normales = new Vector3[vertList.Count];
        for (int i = 0; i < normales.Length; i++)
        {
            normales[i] = vertList[i].normalized;
        }

        mesh.normals = normales;

        mesh.RecalculateBounds();
        mesh.Optimize();
        return(mesh);
    }
Exemple #3
0
        protected override void OnInput(Input input, Collider collider, Camera camera)
        {
            if (this.previousHitVector == InvalidVector && input.InputState == InputState.Pressed)
            {
                RaycastHit hit;

                if (collider.Raycast(camera.ScreenPointToRay(input.CurrentPosition), out hit, float.MaxValue))
                {
                    this.previousHitVector = (hit.point - collider.transform.position).normalized;
                    return;
                }
            }
            else if (this.previousHitVector == InvalidVector || Time.deltaTime == 0.0f)
            {
                return;
            }

            Transform colliderTransform = collider.transform;
            Vector3   colliderPosition  = colliderTransform.position;

            Plane interactablePlane;

            if (this.rotationalAxis == Axis.X)
            {
                interactablePlane = new Plane(colliderPosition, colliderPosition + colliderTransform.up, colliderPosition + colliderTransform.forward);
            }
            else if (this.rotationalAxis == Axis.Y)
            {
                interactablePlane = new Plane(colliderPosition, colliderPosition + colliderTransform.forward, colliderPosition + colliderTransform.right);
            }
            else if (this.rotationalAxis == Axis.Z)
            {
                interactablePlane = new Plane(colliderPosition, colliderPosition + colliderTransform.up, colliderPosition + colliderTransform.right);
            }
            else
            {
                Debug.LogErrorFormat("CircleInteractable found unknown rotationalAxis {0}", this.rotationalAxis);
                interactablePlane = default(Plane);
            }

            Ray inputRay = camera.ScreenPointToRay(input.CurrentPosition);

            float enter;

            if (interactablePlane.Raycast(inputRay, out enter) == false)
            {
                // if we didnt' hit the plane
                this.rotationalVelocity = this.useRotationalVelocity ? this.previousVelocity : 0.0f;
                this.previousHitVector  = InvalidVector;
                this.previousVelocity   = 0.0f;

                return;
            }

            // calculating the current hit vector
            Vector3 hitPoint         = inputRay.GetPoint(enter);
            Vector3 currentHitVector = (hitPoint - collider.transform.position).normalized;

            float   cosTheta = Vector3.Dot(currentHitVector, this.previousHitVector);
            Vector3 cross    = Vector3.Cross(this.previousHitVector, currentHitVector);
            float   theta    = 0.0f;

            // NOTE [bgish]: Sometimes, if cosTheta is too close to 1, but slightly off (by 1 bit), it turns costTheta into a NaN and breaks every
            //               00111111 10000000 00000000 00000000 - C# thinks it's 1.00000000 and this is fine (0x3F800000)
            //               00111111 10000000 00000000 00000001 - C# thinks it's 1.00000000 and this is bad  (0x3F800001)
            //               Debug.Log("0x3F800000 = " + Mathf.Acos(BitConverter.ToSingle(BitConverter.GetBytes(0x3F800000), 0)));  // 0x3F800000 = 1
            //               Debug.Log("0x3F800001 = " + Mathf.Acos(BitConverter.ToSingle(BitConverter.GetBytes(0x3F800001), 0)));  // 0x3F800001 = NaN
            if (cosTheta < 0.999999f)
            {
                bool didFingerMove = (input.PreviousPosition - input.CurrentPosition).sqrMagnitude > minimumPixelMovementSquared;

                if (didFingerMove)
                {
                    Vector3 crossVector;

                    if (this.rotationalAxis == Axis.X)
                    {
                        crossVector = collider.transform.right;
                    }
                    else if (this.rotationalAxis == Axis.Y)
                    {
                        crossVector = collider.transform.up;
                    }
                    else if (this.rotationalAxis == Axis.Z)
                    {
                        crossVector = collider.transform.forward;
                    }
                    else
                    {
                        Debug.LogErrorFormat("CircleInteractable found unknown rotationalAxis {0}", this.rotationalAxis);
                        crossVector = Vector3.zero;
                    }

                    theta = Mathf.Acos(cosTheta) * 180.0f / Mathf.PI * (Vector3.Dot(cross, crossVector) > 0 ? 1 : -1);
                }
            }

            this.Rotation += theta;

            if (input.InputState == InputState.Released)
            {
                this.rotationalVelocity = this.useRotationalVelocity ? Mathf.Clamp(this.previousVelocity, -this.maxRotationalVelocity, this.maxRotationalVelocity) : 0.0f;
                this.previousVelocity   = 0.0f;
            }
            else
            {
                this.rotationalVelocity = 0.0f;
                this.previousVelocity   = theta / Time.deltaTime;
            }

            this.previousHitVector = input.InputState == InputState.Released ? InvalidVector : currentHitVector;
        }
    void OnWizardCreate()
    {
        GameObject sphere = new GameObject();

        if (!string.IsNullOrEmpty(optionalName))
        {
            sphere.name = optionalName;
        }
        else
        {
            sphere.name = "IcoSphere";
        }

        if (!createAtOrigin && cam)
        {
            sphere.transform.position = cam.transform.position + cam.transform.forward * 5.0f;
        }
        else
        {
            sphere.transform.position = Vector3.zero;
        }

        MeshFilter filter = (MeshFilter)sphere.AddComponent(typeof(MeshFilter));

        sphere.AddComponent(typeof(MeshRenderer));

        string anchorId;

        switch (anchor)
        {
        case AnchorPoint.Center:
        default:
            anchorId = "C";
            break;
        }
        string sphereAssetName = sphere.name + recursionLevel + anchorId + ".asset";
        Mesh   mesh            = (Mesh)AssetDatabase.LoadAssetAtPath("Assets/Editor/" + sphereAssetName, typeof(Mesh));

        if (mesh == null)
        {
            mesh      = new Mesh();
            mesh.name = sphere.name;

            List <Vector3>         vertList = new List <Vector3>();
            Dictionary <long, int> middlePointIndexCache = new Dictionary <long, int>();

            // create 12 vertices of a icosahedron
            float t = (1f + Mathf.Sqrt(5f)) / 2f;

            vertList.Add(new Vector3(-1f, t, 0f).normalized *radius);
            vertList.Add(new Vector3(1f, t, 0f).normalized *radius);
            vertList.Add(new Vector3(-1f, -t, 0f).normalized *radius);
            vertList.Add(new Vector3(1f, -t, 0f).normalized *radius);

            vertList.Add(new Vector3(0f, -1f, t).normalized *radius);
            vertList.Add(new Vector3(0f, 1f, t).normalized *radius);
            vertList.Add(new Vector3(0f, -1f, -t).normalized *radius);
            vertList.Add(new Vector3(0f, 1f, -t).normalized *radius);

            vertList.Add(new Vector3(t, 0f, -1f).normalized *radius);
            vertList.Add(new Vector3(t, 0f, 1f).normalized *radius);
            vertList.Add(new Vector3(-t, 0f, -1f).normalized *radius);
            vertList.Add(new Vector3(-t, 0f, 1f).normalized *radius);


            // create 20 triangles of the icosahedron
            List <TriangleIndices> faces = new List <TriangleIndices>();

            // 5 faces around point 0
            faces.Add(new TriangleIndices(0, 11, 5));
            faces.Add(new TriangleIndices(0, 5, 1));
            faces.Add(new TriangleIndices(0, 1, 7));
            faces.Add(new TriangleIndices(0, 7, 10));
            faces.Add(new TriangleIndices(0, 10, 11));

            // 5 adjacent faces
            faces.Add(new TriangleIndices(1, 5, 9));
            faces.Add(new TriangleIndices(5, 11, 4));
            faces.Add(new TriangleIndices(11, 10, 2));
            faces.Add(new TriangleIndices(10, 7, 6));
            faces.Add(new TriangleIndices(7, 1, 8));

            // 5 faces around point 3
            faces.Add(new TriangleIndices(3, 9, 4));
            faces.Add(new TriangleIndices(3, 4, 2));
            faces.Add(new TriangleIndices(3, 2, 6));
            faces.Add(new TriangleIndices(3, 6, 8));
            faces.Add(new TriangleIndices(3, 8, 9));

            // 5 adjacent faces
            faces.Add(new TriangleIndices(4, 9, 5));
            faces.Add(new TriangleIndices(2, 4, 11));
            faces.Add(new TriangleIndices(6, 2, 10));
            faces.Add(new TriangleIndices(8, 6, 7));
            faces.Add(new TriangleIndices(9, 8, 1));


            // refine triangles
            for (int i = 0; i < recursionLevel; i++)
            {
                List <TriangleIndices> faces2 = new List <TriangleIndices>();
                foreach (var tri in faces)
                {
                    // replace triangle by 4 triangles
                    int a = getMiddlePoint(tri.v1, tri.v2, ref vertList, ref middlePointIndexCache, radius);
                    int b = getMiddlePoint(tri.v2, tri.v3, ref vertList, ref middlePointIndexCache, radius);
                    int c = getMiddlePoint(tri.v3, tri.v1, ref vertList, ref middlePointIndexCache, radius);

                    faces2.Add(new TriangleIndices(tri.v1, a, c));
                    faces2.Add(new TriangleIndices(tri.v2, b, a));
                    faces2.Add(new TriangleIndices(tri.v3, c, b));
                    faces2.Add(new TriangleIndices(a, b, c));
                }
                faces = faces2;
            }

            mesh.vertices = vertList.ToArray();

            List <int> triList = new List <int>();
            for (int i = 0; i < faces.Count; i++)
            {
                triList.Add(faces[i].v1);
                triList.Add(faces[i].v2);
                triList.Add(faces[i].v3);
            }
            mesh.triangles = triList.ToArray();

            var       nVertices = mesh.vertices;
            Vector2[] UVs       = new Vector2[nVertices.Length];

            for (var i = 0; i < nVertices.Length; i++)
            {
                var     unitVector = nVertices[i].normalized;
                Vector2 ICOuv      = new Vector2(0, 0);
                ICOuv.x = (Mathf.Atan2(unitVector.x, unitVector.z) + Mathf.PI) / Mathf.PI / 2;
                ICOuv.y = (Mathf.Acos(unitVector.y) + Mathf.PI) / Mathf.PI - 1;
                UVs[i]  = new Vector2(ICOuv.x, ICOuv.y);
            }

            mesh.uv = UVs;

            Vector3[] normales = new Vector3[vertList.Count];
            for (int i = 0; i < normales.Length; i++)
            {
                normales[i] = vertList[i].normalized;
            }

            mesh.normals = normales;

            mesh.RecalculateBounds();
            //mesh.Optimize();

            AssetDatabase.CreateAsset(mesh, "Assets/Editor/" + sphereAssetName);
            AssetDatabase.SaveAssets();
        }

        filter.sharedMesh = mesh;
        mesh.RecalculateBounds();

        if (addCollider)
        {
            sphere.AddComponent(typeof(BoxCollider));
        }

        Selection.activeObject = sphere;
    }
Exemple #5
0
    void FixedUpdate()
    {
        //gravity
        if (isCarGrounded())
        {
            if (gravityFlag)
            {
                StartCoroutine("AdjustGravity");
            }
            if (ignoreGravityDirection)
            {
                carRigidbody.AddForce(-carUp.normalized * gravity * carRigidbody.mass / 2.5f);
            }
            else
            {
                carRigidbody.AddForce(-carUp.normalized * gravity * carRigidbody.mass);
            }
            gravityDirection = -carUp;
        }
        else
        {
            if (ignoreGravityDirection)
            {
                carRigidbody.AddForce(-carUp.normalized * gravity * carRigidbody.mass / 2.5f);
            }
            else
            {
                carRigidbody.AddForce(Vector3.down * gravity * carRigidbody.mass);
            }
        }

        float angleBetween = Mathf.Acos(Vector3.Dot(Vector3.up, transform.up)) * 180 / Mathf.PI;

        if (currentSpeed < maxSpeed + boostSpeed + boostPadSpeed && (isCarGrounded() || angleBetween < 20))
        {
            // apply the engine force to the rigidbody
            carRigidbody.AddForce(engineForce * Time.deltaTime);
        }
        else
        {
            cheatPhysics();
        }

        // turn car
        float tempMaxTurnSpeed = maxTurnAngle;

        if (drift)
        {
            tempMaxTurnSpeed *= driftStrength;
        }



        if (currentTurnSpeed < tempMaxTurnSpeed || relativeAngularVel.y * horizontal < 0f)
        {
            if (!isCarGrounded())
            {
                turnVec = turnVec * inAirTurnMultiplier;
            }
            if (relativeAngularVel.y * horizontal < 0f)
            {
                carRigidbody.AddTorque(turnBackMultiplier * turnVec * Time.deltaTime);
            }
            else
            {
                carRigidbody.AddTorque(turnVec * Time.deltaTime);
            }
        }

        if (Mathf.Abs(horizontal) >= deadZone && isCarGrounded())
        {
            carRigidbody.angularDrag = 0f;
        }
        else
        {
            carRigidbody.angularDrag = 10f;
        }

        if ((Mathf.Abs(throttle) >= deadZone && Mathf.Abs(reverse) <= deadZone || Mathf.Abs(reverse) >= deadZone && Mathf.Abs(throttle) <= deadZone) || !isCarGrounded() || isBoosting)
        {
            carRigidbody.drag = 0f;
        }
        else
        {
            carRigidbody.drag = deceleration;
        }

        // apply forces to our rigidbody for grip
        carRigidbody.AddForce(imp * Time.deltaTime);

        if (GetComponent <VehicleInput>())
        {
            if (onCorkscrew)
            {
                if (cineCamera.GetCinemachineComponent <CinemachineOrbitalTransposer>().m_XDamping != .5f)
                {
                    cineCamera.GetCinemachineComponent <CinemachineOrbitalTransposer>().m_XDamping =
                        Mathf.Lerp(cineCamera.GetCinemachineComponent <CinemachineOrbitalTransposer>().m_XDamping, .5f, Time.deltaTime);
                }
            }
        }

        if (Physics.Raycast(transform.position, carUp, out hit, 5f, LayerMask.GetMask("Ground")))
        {
            GetComponent <CarHealthBehavior>().Kill();
        }
    }
Exemple #6
0
    // Running the solver - all the joints are iterated through once every frame
    void Update()
    {
        if (ready)
        {
            if (!offsetComputed)
            {
                Qoffset = Quaternion.Inverse(joints[joints.Length - 1].transform.rotation) * target.transform.rotation;
                Quaternion Qjoint = joints[joints.Length - 1].transform.rotation;
                //Quaternion Qtarget = Qjoint * Qoffset;
                QoffsetINV     = Quaternion.Inverse(Qoffset);
                offsetComputed = true;
            }

            joints[joints.Length - 1].transform.rotation = target.transform.rotation * QoffsetINV;

            // if the target hasn't been reached
            if (!done)
            {
                // if the Max number of tries hasn't been reached
                if (tries <= Mtries && Vector3.Distance(joints[joints.Length - 1].transform.position, target.transform.position) > epsilon)
                {
                    // starting from the second last joint (the last being the end effector)
                    // going back up to the root
                    for (int i = joints.Length - 2; i >= 0; i--)
                    {
                        // The vector from the ith joint to the end effector
                        Vector3 r1 = joints[joints.Length - 1].transform.position - joints[i].transform.position;
                        // The vector from the ith joint to the target
                        Vector3 r2 = target.transform.position - joints[i].transform.position;

                        // to avoid dividing by tiny numbers
                        if (r1.magnitude * r2.magnitude <= 0.001f)
                        {
                            // cos component will be 1 and sin will be 0
                            cos[i] = 1;
                            sin[i] = 0;
                        }
                        else
                        {
                            // find the components using dot and cross product
                            cos[i] = Vector3.Dot(r1, r2) / (r1.magnitude * r2.magnitude);
                            sin[i] = (Vector3.Cross(r1, r2)).magnitude / (r1.magnitude * r2.magnitude);
                        }

                        // The axis of rotation is basically the
                        // unit vector along the cross product
                        Vector3 axis = (Vector3.Cross(r1, r2)) / (r1.magnitude * r2.magnitude);

                        // find the angle between r1 and r2 (and clamp values of cos to avoid errors)
                        theta[i] = Mathf.Acos(Mathf.Max(-1, Mathf.Min(1, cos[i])));
                        // invert angle if sin component is negative
                        if (sin[i] < 0.0f)
                        {
                            theta[i] = -theta[i];
                        }
                        // obtain an angle value between -pi and pi, and then convert to degrees
                        theta[i] = (float)SimpleAngle(theta[i]) * Mathf.Rad2Deg;
                        // rotate the ith joint along the axis by theta degrees in the world space.
                        joints[i].transform.Rotate(axis, theta[i], Space.World);
                    }

                    // increment tries
                    tries++;
                }
            }

            // find the difference in the positions of the end effector and the target
            float dist = Vector3.Distance(joints[joints.Length - 1].transform.position, target.transform.position);

            // if target is within reach (within epsilon) then the process is done
            done = dist < epsilon;

            // the target has moved, reset tries to 0 and change tpos
            if (target.transform.position != tpos)
            {
                tries = 0;
                tpos  = target.transform.position;
            }
        }
    }
        protected void UpdateDeltaSpeed(ref float frontDeltaSpeed, ref float straffDeltaSpeed, ref bool frontControlled, ref bool straffControlled)
        {
            velocity = transform.InverseTransformDirection(characterController.velocity);

            if (DestPositionActive)
            {
                destDirection.x = destPosition.x - transform.position.x;
                destDirection.z = destPosition.z - transform.position.z;
                destDistance    = destDirection.magnitude;
                destDirection.Normalize();

                destPan = Mathf.Acos(destDirection.z) * Mathf.Rad2Deg;
                if (destDirection.x < 0)
                {
                    destPan = -destPan;
                }

                destDirection = transform.InverseTransformDirection(destDirection);

                if (destDistance < playerWidth * 2)
                {
                    DestPositionActive = false;
                }
                else
                {
                    frontDeltaSpeed  += acceleration * (destDirection.z * characterSpeedKPH * 0.2777777f - FrontSpeed) * Time.deltaTime;
                    straffDeltaSpeed += acceleration * (destDirection.x * characterSpeedKPH * 0.2777777f - StraffSpeed) * Time.deltaTime;
                    frontControlled   = true;
                    straffControlled  = true;
                    UpdateHeadBobber(destDirection.z, 0.0f);
                }


                float speed = velocity.magnitude;
                if (speed < 0.3f)
                {
                    if (!IsStuck)
                    {
                        if (destPositionActiveStuckTime < 0)
                        {
                            destPositionActiveStuckTime = Time.time;
                        }
                        else if (Time.time - destPositionActiveStuckTime > timeBeforeStuckDetection)
                        {
                            IsStuck = true;
                        }
                    }
                }
                else
                {
                    destPositionActiveStuckTime = -1;
                    if (IsStuck)
                    {
                        IsStuck = false;
                    }
                }
            }
            else
            {
                destPanActive = false;
            }
        }
    // move agent towards destination
    void MoveTowardsDestination()
    {
        // if there are no more path nodes, stop moving
        if (!HasDestination())
        {
            _animator.SetBool("IsRunning", false);
            m_agent.StopAngularVelocity();
            return;
        }

        _animator.SetBool("IsRunning", true);

        // calculate all movement and speeds angles etc for moving towards destination
        Vector3 destination = m_pathList[0];

        if (_currentBallTarget)
        {
            if (_currentBallTarget.GetComponent <BallProjectile>().GetIsHeld())
            {
                ResetDestinations();
                return;
            }

            destination = _currentBallTarget.transform.position;
        }

        // check if destination is on correct side of court
        if (_isBlue)
        {
            if (destination.z < 0)
            {
                _currentBallTarget = null;
                m_pathList.Clear();

                /*destination = GenerateRandomLocation(_isBlue);
                 * m_pathList.Add(destination);*/
                ScanForObjects();
                destination = m_pathList[0];
            }
        }
        else
        {
            if (destination.z > 0)
            {
                _currentBallTarget = null;
                m_pathList.Clear();

                /*destination = GenerateRandomLocation(_isBlue);
                 * m_pathList.Add(destination);*/
                ScanForObjects();
                destination = m_pathList[0];
            }
        }

        Vector3 toDestination         = destination - m_agent.transform.position;
        float   distanceToDestination = toDestination.magnitude;

        toDestination.Normalize();
        float lookAtToDestinationDot = Vector3.Dot(m_agent.transform.forward, toDestination);
        float rightToDestinationDot  = Vector3.Dot(m_agent.transform.right, toDestination);
        float toDestinationAngle     = Mathf.Rad2Deg * Mathf.Acos(lookAtToDestinationDot);

        // generate list of speed considerations to pass to calculate functions
        List <float> speedConsiderations = new List <float>();

        float distanceConsideration   = CalculateConsiderationValue(distanceToDestination, m_destinationBuffer, m_maxSpeedDistance);
        float angleConsideration      = CalculateConsiderationValue(toDestinationAngle, m_minAngularSpeedAngle, m_maxAngularSpeedAngle);
        float speedAngleConsideration = 1.0f - angleConsideration;

        speedConsiderations.Add(distanceConsideration);
        speedConsiderations.Add(speedAngleConsideration);

        // set the agents speed and angular speed based on list of considerations generated earlier
        float speed = CalculateConsiderationUtil(speedConsiderations) * m_agent.m_linearMaxSpeed;

        m_agent.linearSpeed = speed;
        float angularSpeed = angleConsideration * m_agent.m_angularMaxSpeed;

        m_agent.angularSpeed = angularSpeed;

        //how do we face our destination
        bool shouldTurnRight = rightToDestinationDot > Mathf.Epsilon;

        if (shouldTurnRight)
        {
            m_agent.TurnRight();
        }
        else
        {
            m_agent.TurnLeft();
        }


        if (distanceToDestination > m_destinationBuffer)
        {
            m_agent.MoveForwards();
        }
        else if (_currentBallTarget)
        {
            PickUpBall();
        }
    }
    void Start()
    {
        //Vector3.Angle() [0,180]
        //两个向量的夹角
        Vector3 a0     = new Vector3(0, 1, 1);
        Vector3 a1     = new Vector3(2, 1, 0);
        float   angle0 = Vector3.Angle(a0, a1);

        Debug.Log(a0 + " " + a1 + " 以原点为夹角的角度 " + angle0);
        //计算以b0为原点,b0a0,b0a1的夹角
        Vector3 b0     = new Vector3(2, 2, 2);
        float   angle1 = Vector3.Angle(b0 - a0, b0 - a1);

        Debug.Log(a0 + " " + a1 + " 以b0为夹角的角度 " + angle1);

        //叉积Vector3.Cross()
        //得到同时垂直于两个这两个向量的法向量
        Vector3 cross = Vector3.Cross(a0.normalized, a1.normalized);

        Debug.DrawLine(Vector3.zero, a0, Color.red, 10000);
        Debug.DrawLine(Vector3.zero, a1, Color.red, 10000);
        Debug.DrawLine(Vector3.zero, cross, Color.red, 10000);
        Debug.Log("cross = " + cross);
        //弧度
        float radians = Mathf.Asin(Vector3.Distance(Vector3.zero, Vector3.Cross(a0.normalized, a1.normalized)));
        //夹角
        float angle2 = radians * Mathf.Rad2Deg;

        Debug.Log(a0 + " " + a1 + " 以原点为夹角的角度 " + angle2 + "  弧度 " + radians + " 叉积 " + cross);

        if (cross.y > 0)
        {
            //a1在a0顺时针右边
        }
        else if (cross.y < 0)
        {
            //a1在a0逆时针左边
        }
        else
        {
            //a1和a0平行
        }

        //点积Vector3.Dot()
        float dot    = Vector3.Dot(a0.normalized, a1.normalized);
        float angle3 = Mathf.Acos(Vector3.Dot(a0.normalized, a1.normalized)) * Mathf.Rad2Deg;

        Debug.Log(a0 + " " + a1 + " " + "以原点为夹角的角度 " + angle3 + " 弧度 " + radians + " 点积 " + dot);
        if (dot > 0)
        {
            //a1在a0前方
        }
        else if (dot < 0)
        {
            //a1在a0后方
        }
        else
        {
            //1正前方-1正后方
        }

        //Vector3.BetweenAngle
        //返回一个向量的拷贝,并限制最大长度
        Vector3 v0             = new Vector3(0, 5, 0);
        Vector3 clampMagnitude = Vector3.ClampMagnitude(v0, 3);

        Debug.Log("clampMagnitude = " + clampMagnitude);

        //Vector3.Magnitude
        //返回向量的长度
        float magnitude = Vector3.Magnitude(new Vector3(1, 5, 0));

        Debug.Log("magnitude = " + magnitude);
        //Vector3.SqrMagnitude
        //返回向量长度的平方
        float sqrMagnitude = Vector3.SqrMagnitude(new Vector3(1, 5, 0));

        Debug.Log("sqrMagnitude = " + sqrMagnitude);

        //Vector3.Max
        //返回两个向量的最大组成
        Vector3 max = Vector3.Max(new Vector3(10, 3, 5), new Vector3(1, 4, 100));

        Debug.Log("max = " + max);
        //Vector3.Min
        //返回两个向量的最小组成
        Vector3 min = Vector3.Min(new Vector3(10, 3, 5), new Vector3(1, 4, 100));

        Debug.Log("min = " + min);

        //Vector3.Normalized
        //归一化,只比较方向不比较长度
        Vector3 normalized = (new Vector3(10, 2, 3)).normalized;

        Debug.Log("normalized = " + normalized);
        //Vector3.OrthoNormalize
        //归一化并彼此相互垂直对第二个第三个参照第一个进行正交化处理
        Vector3 ort0 = new Vector3(1, 2, 3);
        Vector3 ort1 = new Vector3(4, 5, 6);

        Debug.DrawLine(Vector3.zero, ort0, Color.green, 1000);
        Debug.DrawLine(Vector3.zero, ort1, Color.green, 1000);
        Debug.Log("ort0.normalize = " + ort0.normalized + " ort1.normalize = " + ort1.normalized);
        Vector3.OrthoNormalize(ref ort0, ref ort1);
        Debug.Log("ort0 = " + ort0 + " ort1 = " + ort1);
        Debug.DrawLine(Vector3.zero, ort0, Color.blue, 1000);
        Debug.DrawLine(Vector3.zero, ort1, Color.blue, 1000);

        //Vector3.Project
        //返回p0在p1上的投影向量
        Vector3 p0      = new Vector3(1, 5, 7);
        Vector3 p1      = new Vector3(2, 8, 8);
        Vector3 project = Vector3.Project(p0, p1);

        Debug.Log("Project = " + project);
        //Debug.DrawLine(Vector3.zero, p0, Color.black, 1000);
        //Debug.DrawLine(Vector3.zero, p1, Color.black, 1000);
        //Debug.DrawLine(Vector3.zero, project, Color.blue, 1000);

        //Vector3.Reflect
        //反射向量,沿着reflect1的法线(垂直于reflect1)的反射向量
        Vector3 reflect0 = new Vector3(0, 3, 2);
        Vector3 reflect1 = Vector3.Reflect(reflect0, Vector3.up);

        Debug.DrawLine(Vector3.zero, reflect0, Color.gray, 1000);
        Debug.DrawLine(Vector3.zero, Vector3.up, Color.yellow, 1000);
        Debug.DrawLine(Vector3.zero, reflect1, Color.black, 1000);

        //Vector3.Scale
        //返回向量a和b的乘积
        Vector3 scale = Vector3.Scale(new Vector3(1, 2, 3), new Vector3(4, 5, 6));

        Debug.Log(" scale = " + scale);
    }
Exemple #10
0
        /// Detection Center should be in Global Space.
        protected void UpdateSolitaryBrushDetection(Vector3 vDetectionCenter_GS)
        {
            if (m_CurrentCanvas == null)
            {
                m_CurrentCanvas = App.ActiveCanvas;
            }
            TrTransform canvasPose          = m_CurrentCanvas.Pose;
            Vector3     vDetectionCenter_CS = canvasPose.inverse * vDetectionCenter_GS;
            Transform   rCanvas             = m_CurrentCanvas.transform;
            int         iNumCanvasChildren  = rCanvas.childCount;

            m_TimesUp = false;

            //reset detection if we've moved or adjusted our size
            float fDetectionRadius   = GetSize();
            float fDetectionRadiusSq = fDetectionRadius * fDetectionRadius;

            m_DetectionStopwatch.Reset();
            m_DetectionStopwatch.Start();

            //early out if there's nothing to look at
            if (iNumCanvasChildren > 0 && m_DetectionObjectIndex < iNumCanvasChildren)
            {
                Plane rTestPlane = new Plane();
                m_ResetDetection = false;

                //spin until we've taken up too much time
                while (!m_TimesUp)
                {
                    //check child bounds
                    Transform rChild = rCanvas.GetChild(m_DetectionObjectIndex);
                    if (rChild.gameObject.activeSelf)
                    {
                        MeshFilter rMeshFilter = rChild.GetComponent <MeshFilter>();
                        if (rMeshFilter)
                        {
                            Bounds rMeshBounds = rMeshFilter.mesh.bounds;
                            rMeshBounds.Expand(fDetectionRadius);
                            Vector3 vTransformedCenter = rChild.InverseTransformPoint(vDetectionCenter_CS);

                            if (rMeshBounds.Contains(vTransformedCenter))
                            {
                                //bounds valid, check triangle intersections with sphere
                                int       iMeshVertCount = rMeshFilter.mesh.vertexCount;
                                Vector3[] aVerts         = rMeshFilter.mesh.vertices;
                                Vector3[] aNorms         = rMeshFilter.mesh.normals;
                                while (m_DetectionVertIndex < iMeshVertCount - 2)
                                {
                                    //check to see if we're within the sphere radius to the plane of this triangle
                                    Vector3 vVert = aVerts[m_DetectionVertIndex];
                                    Vector3 vNorm = aNorms[m_DetectionVertIndex];
                                    rTestPlane.SetNormalAndPosition(vNorm, vVert);
                                    float fDistToPlane = rTestPlane.GetDistanceToPoint(vTransformedCenter);
                                    if (Mathf.Abs(fDistToPlane) < fDetectionRadius)
                                    {
                                        //we're within the radius to this triangle's plane, find the point projected on to the plane
                                        fDistToPlane *= -1.0f;
                                        Vector3 vPlaneOffsetVector = vNorm * fDistToPlane;
                                        Vector3 vPlaneIntersection = vTransformedCenter - vPlaneOffsetVector;

                                        Vector3 vVert2 = aVerts[m_DetectionVertIndex + 1];
                                        Vector3 vVert3 = aVerts[m_DetectionVertIndex + 2];

                                        //walk the projected point toward the triangle center to find the triangle test position
                                        Vector3 vTriCenter = (vVert + vVert2 + vVert3) * 0.33333f;

                                        bool    bIntersecting     = false;
                                        Vector3 vPointToTriCenter = vTriCenter - vTransformedCenter;
                                        if (vPointToTriCenter.sqrMagnitude < fDetectionRadiusSq)
                                        {
                                            //if the triangle center is within the detection distance, we're definitely intersecting
                                            bIntersecting = true;
                                        }
                                        else
                                        {
                                            //figure out how far we have left to move toward the tri-center
                                            float fNormAngle = Mathf.Acos(Mathf.Abs(fDistToPlane) / fDetectionRadius);
                                            float fDistLeft  = Mathf.Sin(fNormAngle) * fDetectionRadius;

                                            Vector3 vToTriCenter = vTriCenter - vPlaneIntersection;
                                            vToTriCenter.Normalize();
                                            vToTriCenter       *= fDistLeft;
                                            vPlaneIntersection += vToTriCenter;

                                            //see if this projected point is in the triangle
                                            if (PointInTriangle(ref vPlaneIntersection, ref vVert, ref vVert2, ref vVert3))
                                            {
                                                bIntersecting = true;
                                            }
                                        }

                                        if (bIntersecting)
                                        {
                                            if (HandleIntersectionWithSolitaryObject(rChild.gameObject))
                                            {
                                                DoIntersectionResets();
                                                break;
                                            }
                                        }
                                    }

                                    //after each triangle, check our time
                                    m_DetectionVertIndex += 3;
                                    m_TimesUp             = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks;
                                    if (m_TimesUp)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    //if we're not flagged as done, we just finished this object, so move on to the next
                    if (!m_TimesUp)
                    {
                        //move to the next object
                        ++m_DetectionObjectIndex;

                        m_DetectionVertIndex = 0;
                        if (m_DetectionObjectIndex >= iNumCanvasChildren)
                        {
                            //if we reached the end of the line, we're done
                            break;
                        }

                        //might as well check our clock per object
                        m_TimesUp = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks;
                    }
                }
            }
            m_DetectionStopwatch.Stop();
        }
Exemple #11
0

        
Exemple #12
0
        /// Detection Center should be in Global Space.
        protected void UpdateBatchedBrushDetection(Vector3 vDetectionCenter_GS)
        {
            // The CPU intersection code still needs to be updated to iterate over multiple canvases.
            //
            // TODO: Update CPU intersection checking to work on multiple canvases,
            //       then get rid of automatic defaulting to ActiveCanvas.
            //       Possibly let m_CurrentCanvas be null to represent a desire to intersect
            //       with all canvases.
            if (m_CurrentCanvas == null)
            {
                m_CurrentCanvas = App.ActiveCanvas;
            }

            // If we changed canvases, abandon any progress we made on checking for
            // intersections in the previous canvas.
            if (m_CurrentCanvas != m_PreviousCanvas)
            {
                ResetDetection();
                m_PreviousCanvas = m_CurrentCanvas;
            }

            TrTransform canvasPose          = m_CurrentCanvas.Pose;
            Vector3     vDetectionCenter_CS = canvasPose.inverse * vDetectionCenter_GS;

            m_TimesUp = false;

            // Reset detection if we've moved or adjusted our size
            float fDetectionRadius_CS   = GetSize() / canvasPose.scale;
            float fDetectionRadiusSq_CS = fDetectionRadius_CS * fDetectionRadius_CS;

            // Start the timer!
            m_DetectionStopwatch.Reset();
            m_DetectionStopwatch.Start();

            int  iSanityCheck    = 10000;
            bool bNothingChecked = true;

            if (App.Config.m_GpuIntersectionEnabled)
            {
                // Run GPU intersection if enabled; will update m_TimesUp.
                if (UpdateGpuIntersection(vDetectionCenter_GS, GetSize()))
                {
                    IntersectionHappenedThisFrame();
                    m_DetectionStopwatch.Stop();
                    DoIntersectionResets();
                    return;
                }
            }

            m_TimesUp = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks;

            //check batch pools first
            int iNumBatchPools = m_CurrentCanvas.BatchManager.GetNumBatchPools();

            if (!App.Config.m_GpuIntersectionEnabled &&
                iNumBatchPools > 0 &&
                m_BatchPoolIndex < iNumBatchPools)
            {
                bNothingChecked  = false;
                m_ResetDetection = false;
                Plane     rTestPlane = new Plane();
                BatchPool rPool      = m_CurrentCanvas.BatchManager.GetBatchPool(m_BatchPoolIndex);

                //spin until we've taken up too much time
                while (!m_TimesUp)
                {
                    --iSanityCheck;
                    if (iSanityCheck == 0)
                    {
                        Batch tmpBatch = rPool.m_Batches[m_BatchObjectIndex];
                        Debug.LogErrorFormat("Stroke while loop error.  NumPools({0}) BatchPoolIndex({1}) NumBatchStrokes({2}) BatchStrokeIndex({3}) NumStrokeGroups({4})",
                                             iNumBatchPools, m_BatchPoolIndex, rPool.m_Batches.Count, m_BatchObjectIndex, tmpBatch.m_Groups.Count);
                    }

                    Batch batch = rPool.m_Batches[m_BatchObjectIndex];
                    if (m_BatchVertGroupIndex < batch.m_Groups.Count)
                    {
                        var    subset      = batch.m_Groups[m_BatchVertGroupIndex];
                        Bounds rMeshBounds = subset.m_Bounds;
                        rMeshBounds.Expand(2.0f * fDetectionRadius_CS);

                        if (subset.m_Active && rMeshBounds.Contains(vDetectionCenter_CS))
                        {
                            //bounds valid, check triangle intersections with sphere
                            int       nTriIndices = subset.m_nTriIndex;
                            Vector3[] aVerts; int nVerts;
                            int[]     aTris; int nTris;
                            batch.GetTriangles(out aVerts, out nVerts, out aTris, out nTris);
                            while (m_BatchTriIndexIndex < nTriIndices - 2)
                            {
                                //check to see if we're within the brush size (plus some) radius to this triangle
                                int     iTriIndex            = subset.m_iTriIndex + m_BatchTriIndexIndex;
                                Vector3 v0                   = aVerts[aTris[iTriIndex]];
                                Vector3 v1                   = aVerts[aTris[iTriIndex + 1]];
                                Vector3 v2                   = aVerts[aTris[iTriIndex + 2]];
                                Vector3 vTriCenter           = (v0 + v1 + v2) * 0.33333f;
                                Vector3 vToTestCenter        = vDetectionCenter_CS - vTriCenter;
                                float   fTestSphereRadius_CS = Vector3.Distance(v1, v2) + fDetectionRadius_CS;
                                if (vToTestCenter.sqrMagnitude < fTestSphereRadius_CS * fTestSphereRadius_CS)
                                {
                                    //check to see if we're within the sphere radius to the plane of this triangle
                                    Vector3 vNorm = Vector3.Cross(v1 - v0, v2 - v0).normalized;
                                    rTestPlane.SetNormalAndPosition(vNorm, v0);
                                    float fDistToPlane = rTestPlane.GetDistanceToPoint(vDetectionCenter_CS);
                                    if (Mathf.Abs(fDistToPlane) < fDetectionRadius_CS)
                                    {
                                        //we're within the radius to this triangle's plane, find the point projected on to the plane
                                        fDistToPlane *= -1.0f;
                                        Vector3 vPlaneOffsetVector = vNorm * fDistToPlane;
                                        Vector3 vPlaneIntersection = vDetectionCenter_CS - vPlaneOffsetVector;

                                        //walk the projected point toward the triangle center to find the triangle test position
                                        bool    bIntersecting     = false;
                                        Vector3 vPointToTriCenter = vTriCenter - vDetectionCenter_CS;
                                        if (vPointToTriCenter.sqrMagnitude < fDetectionRadiusSq_CS)
                                        {
                                            //if the triangle center is within the detection distance, we're definitely intersecting
                                            bIntersecting = true;
                                        } //check against triangle segments
                                        else if (SegmentSphereIntersection(v0, v1, vDetectionCenter_CS, fDetectionRadiusSq_CS))
                                        {
                                            bIntersecting = true;
                                        }
                                        else if (SegmentSphereIntersection(v1, v2, vDetectionCenter_CS, fDetectionRadiusSq_CS))
                                        {
                                            bIntersecting = true;
                                        }
                                        else if (SegmentSphereIntersection(v2, v0, vDetectionCenter_CS, fDetectionRadiusSq_CS))
                                        {
                                            bIntersecting = true;
                                        }
                                        else
                                        {
                                            //figure out how far we have left to move toward the tri-center
                                            float fNormAngle = Mathf.Acos(Mathf.Abs(fDistToPlane) / fDetectionRadius_CS);
                                            float fDistLeft  = Mathf.Sin(fNormAngle) * fDetectionRadius_CS;

                                            Vector3 vToTriCenter = vTriCenter - vPlaneIntersection;
                                            vToTriCenter.Normalize();
                                            vToTriCenter       *= fDistLeft;
                                            vPlaneIntersection += vToTriCenter;

                                            //see if this projected point is in the triangle
                                            if (PointInTriangle(ref vPlaneIntersection, ref v0, ref v1, ref v2))
                                            {
                                                bIntersecting = true;
                                            }
                                        }

                                        if (bIntersecting)
                                        {
                                            if (HandleIntersectionWithBatchedStroke(subset))
                                            {
                                                DoIntersectionResets();
                                                break;
                                            }
                                        }
                                    }
                                }

                                //after each triangle, check our time
                                m_BatchTriIndexIndex += 3;
                                m_TimesUp             = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks;
                                if (m_TimesUp)
                                {
                                    break;
                                }
                            }
                        }
                    }

                    //if we're not flagged as done, we just finished this group, so move on to the next group
                    if (!m_TimesUp)
                    {
                        m_BatchTriIndexIndex = 0;
                        ++m_BatchVertGroupIndex;

                        //if we're done with groups, go to the next object
                        if (m_BatchVertGroupIndex >= batch.m_Groups.Count)
                        {
                            m_BatchVertGroupIndex = 0;
                            ++m_BatchObjectIndex;

                            //aaaand if we're done with objects, go on to the next pool
                            if (m_BatchObjectIndex >= rPool.m_Batches.Count)
                            {
                                m_BatchObjectIndex = 0;
                                ++m_BatchPoolIndex;
                                if (m_BatchPoolIndex >= iNumBatchPools)
                                {
                                    //get out if we've traversed the last pool
                                    break;
                                }
                                rPool = m_CurrentCanvas.BatchManager.GetBatchPool(m_BatchPoolIndex);
                            }
                        }

                        //we check again here in case the early checks fail
                        m_TimesUp = m_DetectionStopwatch.ElapsedTicks > m_TimeSliceInTicks;
                    }
                }
            }

            if (App.Config.m_GpuIntersectionEnabled && m_GpuFutureResult != null)
            {
                // We have an intersection test in flight, make sure we don't reset detection.
                // This ensures consistency between collision tests and avoids strobing of the result (e.g.
                // without this, one test will return "no result" and the next may return some result and this
                // oscillation will continue).
                bNothingChecked  = false;
                m_ResetDetection = false;
                return;
            }

            // If our scene doesn't have anything in it, reset our detection.
            if (bNothingChecked)
            {
                m_ResetDetection = true;
            }

            m_DetectionStopwatch.Stop();
        }
Exemple #13
0
        public static float Radius3DHandle(Quaternion rotation, Vector3 position, float radius, float minRadius = 0, float maxRadius = float.PositiveInfinity)
        {
            minRadius = Mathf.Abs(minRadius);
            maxRadius = Mathf.Abs(maxRadius); if (maxRadius < minRadius)
            {
                maxRadius = minRadius;
            }

            const float kEpsilon = 0.000001F;

            var camera               = Camera.current;
            var cameraLocalPos       = SceneHandles.inverseMatrix.MultiplyPoint(camera.transform.position);
            var cameraLocalForward   = SceneHandles.inverseMatrix.MultiplyVector(camera.transform.forward);
            var isCameraInsideSphere = (cameraLocalPos - position).magnitude < radius;
            var isCameraOrthographic = camera.orthographic;

            var isStatic     = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects));
            var prevDisabled = SceneHandles.disabled;
            var prevColor    = SceneHandles.color;

            var forward = rotation * Vector3.forward;
            var up      = rotation * Vector3.up;
            var right   = rotation * Vector3.right;

            bool guiHasChanged = GUI.changed;

            GUI.changed = false;

            Vector3 positiveXDir = right;
            Vector3 negativeXDir = -right;
            Vector3 positiveYDir = up;
            Vector3 negativeYDir = -up;
            Vector3 positiveZDir = forward;
            Vector3 negativeZDir = -forward;

            Vector3 positiveXHandle = position + positiveXDir * radius;
            Vector3 negativeXHandle = position + negativeXDir * radius;
            Vector3 positiveYHandle = position + positiveYDir * radius;
            Vector3 negativeYHandle = position + negativeYDir * radius;
            Vector3 positiveZHandle = position + positiveZDir * radius;
            Vector3 negativeZHandle = position + negativeZDir * radius;

            bool positiveXBackfaced = false;
            bool negativeXBackfaced = false;
            bool positiveYBackfaced = false;
            bool negativeYBackfaced = false;
            bool positiveZBackfaced = false;
            bool negativeZBackfaced = false;

            if (!isCameraInsideSphere)
            {
                float cosV;

                cosV = isCameraOrthographic ? Vector3.Dot(positiveXDir, -cameraLocalForward) :
                       Vector3.Dot(positiveXDir, (cameraLocalPos - positiveXHandle));
                positiveXBackfaced = (cosV < -0.0001f);

                cosV = isCameraOrthographic ? Vector3.Dot(negativeXDir, -cameraLocalForward) :
                       Vector3.Dot(negativeXDir, (cameraLocalPos - negativeXHandle));
                negativeXBackfaced = (cosV < -0.0001f);


                cosV = isCameraOrthographic ? Vector3.Dot(positiveYDir, -cameraLocalForward) :
                       Vector3.Dot(positiveYDir, (cameraLocalPos - positiveYHandle));
                positiveYBackfaced = (cosV < -0.0001f);

                cosV = isCameraOrthographic ? Vector3.Dot(negativeYDir, -cameraLocalForward) :
                       Vector3.Dot(negativeYDir, (cameraLocalPos - negativeYHandle));
                negativeYBackfaced = (cosV < -0.0001f);


                cosV = isCameraOrthographic ? Vector3.Dot(positiveZDir, -cameraLocalForward) :
                       Vector3.Dot(positiveZDir, (cameraLocalPos - positiveZHandle));
                positiveZBackfaced = (cosV < -0.0001f);

                cosV = isCameraOrthographic ? Vector3.Dot(negativeZDir, -cameraLocalForward) :
                       Vector3.Dot(negativeZDir, (cameraLocalPos - negativeZHandle));
                negativeZBackfaced = (cosV < -0.0001f);
            }

            float positiveXSize = UnityEditor.HandleUtility.GetHandleSize(positiveXHandle) * 0.05f * (positiveXBackfaced ? backfaceSizeMultiplier : 1);
            float negativeXSize = UnityEditor.HandleUtility.GetHandleSize(negativeXHandle) * 0.05f * (negativeXBackfaced ? backfaceSizeMultiplier : 1);
            float positiveYSize = UnityEditor.HandleUtility.GetHandleSize(positiveYHandle) * 0.05f * (positiveYBackfaced ? backfaceSizeMultiplier : 1);
            float negativeYSize = UnityEditor.HandleUtility.GetHandleSize(negativeYHandle) * 0.05f * (negativeYBackfaced ? backfaceSizeMultiplier : 1);
            float positiveZSize = UnityEditor.HandleUtility.GetHandleSize(positiveZHandle) * 0.05f * (positiveZBackfaced ? backfaceSizeMultiplier : 1);
            float negativeZSize = UnityEditor.HandleUtility.GetHandleSize(negativeZHandle) * 0.05f * (negativeZBackfaced ? backfaceSizeMultiplier : 1);



            var isDisabled     = isStatic || prevDisabled || Snapping.AxisLocking[0];
            var color          = SceneHandles.StateColor(prevColor, isDisabled, false);
            var backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier);

            GUI.changed        = false;
            SceneHandles.color = positiveXBackfaced ? backfacedColor : color;
            positiveXHandle    = Slider2DHandle(positiveXHandle, Vector3.zero, forward, up, right, positiveXSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(positiveXHandle - position, positiveXDir); guiHasChanged = true;
            }

            GUI.changed        = false;
            SceneHandles.color = negativeXBackfaced ? backfacedColor : color;
            negativeXHandle    = Slider2DHandle(negativeXHandle, Vector3.zero, forward, up, right, negativeXSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(negativeXHandle - position, negativeXDir); guiHasChanged = true;
            }



            isDisabled     = isStatic || prevDisabled || Snapping.AxisLocking[1];
            color          = SceneHandles.StateColor(prevColor, isDisabled, false);
            backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier);

            GUI.changed        = false;
            SceneHandles.color = positiveYBackfaced ? backfacedColor : color;
            positiveYHandle    = Slider2DHandle(positiveYHandle, Vector3.zero, forward, up, right, positiveYSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(positiveYHandle - position, positiveYDir); guiHasChanged = true;
            }

            GUI.changed        = false;
            SceneHandles.color = negativeYBackfaced ? backfacedColor : color;
            negativeYHandle    = Slider2DHandle(negativeYHandle, Vector3.zero, forward, up, right, negativeYSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(negativeYHandle - position, negativeYDir); guiHasChanged = true;
            }



            isDisabled     = isStatic || prevDisabled || Snapping.AxisLocking[2];
            color          = SceneHandles.StateColor(prevColor, isDisabled, false);
            backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier);

            GUI.changed        = false;
            SceneHandles.color = positiveZBackfaced ? backfacedColor : color;
            positiveZHandle    = Slider2DHandle(positiveZHandle, Vector3.zero, up, forward, right, positiveZSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(positiveZHandle - position, positiveZDir); guiHasChanged = true;
            }

            GUI.changed        = false;
            SceneHandles.color = negativeZBackfaced ? backfacedColor : color;
            negativeZHandle    = Slider2DHandle(negativeZHandle, Vector3.zero, up, forward, right, negativeZSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(negativeZHandle - position, negativeZDir); guiHasChanged = true;
            }


            radius = Mathf.Max(minRadius, Mathf.Min(Mathf.Abs(radius), maxRadius));


            GUI.changed |= guiHasChanged;

            if (radius > 0)
            {
                isDisabled     = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]);
                color          = SceneHandles.StateColor(prevColor, isDisabled, false);
                backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier);
                var discOrientations = new Vector3[]
                {
                    rotation *Vector3.right,
                    rotation *Vector3.up,
                    rotation *Vector3.forward
                };

                var currentCamera   = Camera.current;
                var cameraTransform = currentCamera.transform;
                if (currentCamera.orthographic)
                {
                    var planeNormal = cameraTransform.forward;
                    SceneHandles.DrawWireDisc(position, planeNormal, radius);
                    planeNormal.Normalize();
                    for (int i = 0; i < 3; i++)
                    {
                        var discOrientation = discOrientations[i];
                        var discTangent     = Vector3.Cross(discOrientation, planeNormal);

                        // we may have view dir locked to one axis
                        if (discTangent.sqrMagnitude > kEpsilon)
                        {
                            SceneHandles.color = color;
                            SceneHandles.DrawWireArc(position, discOrientation, discTangent, 180, radius);
                            SceneHandles.color = backfacedColor;
                            SceneHandles.DrawWireArc(position, discOrientation, discTangent, -180, radius);
                        }
                    }
                }
                else
                {
                    // Since the geometry is transformed by Handles.matrix during rendering, we transform the camera position
                    // by the inverse matrix so that the two-shaded wireframe will have the proper orientation.
                    var invMatrix = SceneHandles.inverseMatrix;

                    var cameraCenter          = cameraTransform.position;
                    var cameraToCenter        = position - invMatrix.MultiplyPoint(cameraCenter);           // vector from camera to center
                    var sqrDistCameraToCenter = cameraToCenter.sqrMagnitude;
                    var sqrRadius             = radius * radius;                                            // squared radius
                    var sqrOffset             = sqrRadius * sqrRadius / sqrDistCameraToCenter;              // squared distance from actual center to drawn disc center
                    var insideAmount          = sqrOffset / sqrRadius;
                    if (insideAmount < 1)
                    {
                        if (Mathf.Abs(sqrDistCameraToCenter) < kEpsilon)
                        {
                            return(radius);
                        }

                        var horizonRadius = Mathf.Sqrt(sqrRadius - sqrOffset);
                        var horizonCenter = position - sqrRadius * cameraToCenter / sqrDistCameraToCenter;
                        SceneHandles.color = color;
                        SceneHandles.DrawWireDisc(horizonCenter, cameraToCenter, horizonRadius);

                        var planeNormal = cameraToCenter.normalized;
                        for (int i = 0; i < 3; i++)
                        {
                            var discOrientation = discOrientations[i];

                            var angleBetweenDiscAndNormal = Mathf.Acos(Vector3.Dot(discOrientation, planeNormal));
                            angleBetweenDiscAndNormal = (Mathf.PI * 0.5f) - Mathf.Min(angleBetweenDiscAndNormal, Mathf.PI - angleBetweenDiscAndNormal);

                            float f = Mathf.Tan(angleBetweenDiscAndNormal);
                            float g = Mathf.Sqrt(sqrOffset + f * f * sqrOffset) / radius;
                            if (g < 1)
                            {
                                var angleToHorizon         = Mathf.Asin(g) * Mathf.Rad2Deg;
                                var discTangent            = Vector3.Cross(discOrientation, planeNormal);
                                var vectorToPointOnHorizon = Quaternion.AngleAxis(angleToHorizon, discOrientation) * discTangent;
                                var horizonArcLength       = (90 - angleToHorizon) * 2.0f;

                                SceneHandles.color = color;
                                SceneHandles.DrawWireArc(position, discOrientation, vectorToPointOnHorizon, horizonArcLength, radius);
                                SceneHandles.color = backfacedColor;
                                SceneHandles.DrawWireArc(position, discOrientation, vectorToPointOnHorizon, horizonArcLength - 360, radius);
                            }
                            else
                            {
                                SceneHandles.color = backfacedColor;
                                SceneHandles.DrawWireDisc(position, discOrientation, radius);
                            }
                        }
                    }
                    else
                    {
                        SceneHandles.color = backfacedColor;
                        for (int i = 0; i < 3; i++)
                        {
                            var discOrientation = discOrientations[i];
                            SceneHandles.DrawWireDisc(position, discOrientation, radius);
                        }
                    }
                }
            }

            SceneHandles.disabled = prevDisabled;
            SceneHandles.color    = prevColor;

            return(radius);
        }
Exemple #14
0
    // TODO Negative m's are missing
    private float AssociatedLegendrePolynomials()
    {
        int l = m_QuantumNumberL;
        int m = m_QuantumNumberM;

        float x = this.transform.position.x;
        float y = this.transform.position.y;
        float z = this.transform.position.z;
        float r = Mathf.Sqrt(x * x + y * y + z * z);

        // Compute spherical coordinates
        float theta = Mathf.Acos(z / r);

        float arg    = Mathf.Cos(theta); // The argument to the polynomial
        float result = 1.0f;             // l=0 gives 1

        if (l == 1)
        {
            if (m == 1)
            {
                result = -Mathf.Sqrt(1f - arg * arg);
            }
            else if (m == 0)
            {
                result = arg;
            }
        }
        else if (l == 2)
        {
            if (m == 2)
            {
                result = 3f * (1f - arg * arg);
            }
            else if (m == 1)
            {
                result = -3f * arg * Mathf.Sqrt(1f - arg * arg);
            }
            else if (m == 0)
            {
                result = 0.5f * (3f * arg * arg - 1f);
            }
        }
        else if (l == 3)
        {
            if (m == 3)
            {
                result = -15f * Mathf.Pow(Mathf.Sqrt(1f - arg * arg), 3.0f);
            }
            else if (m == 2)
            {
                result = 15f * arg * (1f - arg * arg);
            }
            else if (m == 1)
            {
                result = -3f / 2f * (5f * arg * arg - 1f) * Mathf.Sqrt(1f - arg * arg);
            }
            else if (m == 0)
            {
                result = 0.5f * (5f * arg * arg * arg - 3f * arg);
            }
        }
        else
        {
            Debug.LogError("AssociatedLegendrePolynomials() does not take so large aguments");
        }

        return(result);
    }
Exemple #15
0
    void Update()
    {
        character.Move();
#if UNITY_STANDALONE_WIN
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //character.Jump();
            if (!(transform.position.y > 0.25f))
            {
                character.isJump = true;
            }
        }
        float moveDir = Input.GetAxis("Horizontal");
        character.ManualMove(moveDir);

        if (Input.GetKeyDown(KeyCode.J))
        {
            character.RotateLeft();
        }
        else if (Input.GetKeyDown(KeyCode.L))
        {
            character.RotateRight();
        }

        if (Input.GetKeyDown(KeyCode.K))
        {
            character.Slide();
        }

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (exitUI != null)
            {
                exitUI.SetActive(true);
            }
            else
            {
                exitUI = Instantiate(Resources.Load("UiPreFeb/Img_Exit"), GameObject.Find("Canvas").transform) as GameObject;
            }
            GameMode.Instance.gameState = false;
        }
        #region //PC测试
        //if (Input.GetKeyDown(KeyCode.Mouse0))
        //{
        //    startPos = Camera.main.ViewportToScreenPoint(Input.mousePosition);
        //}

        //if (Input.GetKeyDown(KeyCode.Mouse1))
        //{
        //    EndPos = Camera.main.ViewportToScreenPoint(Input.mousePosition);
        //    isInput = true;
        //}
        #endregion
#endif
        #region //手机代码
#if UNITY_ANDROID
        character.ManualMove(Input.acceleration.x);
        if (Input.touchCount == 1)
        {
            if (Input.touches[0].phase == TouchPhase.Began)
            {
                startPos = Input.touches[0].position;
            }

            if (Input.touches[0].phase == TouchPhase.Ended && Input.touches[0].phase != TouchPhase.Canceled)
            {
                EndPos  = Input.touches[0].position;
                isInput = true;
            }
        }
        if (Application.platform == RuntimePlatform.Android && (Input.GetKeyDown(KeyCode.Escape)))
        {
            if (exitUI != null)
            {
                exitUI.SetActive(true);
            }
            else
            {
                exitUI = Instantiate(Resources.Load("UiPreFeb/Img_Exit"), GameObject.Find("Canvas").transform) as GameObject;
            }
            GameMode.Instance.gameState = false;
        }

        if (isInput && GameMode.Instance.gameState)
        {
            Vector2 nowDir    = EndPos - startPos;                                                         //计算手指滑动之间的向量
            float   cosValueX = Vector3.Dot(nowDir, ScreenAixX) / nowDir.magnitude * ScreenAixX.magnitude; //与屏幕坐标的X轴的余弦值
            float   cosValueY = Vector3.Dot(nowDir, ScreenAixY) / nowDir.magnitude * ScreenAixY.magnitude; //与屏幕坐标的Y轴余弦值
            angle = Mathf.Acos(cosValueY) * Mathf.Rad2Deg;

            Debug.Log(angle + " === " + cosValueX + " === " + cosValueY + " === ");
            if (cosValueX < 0)
            {
                if (angle > 45 && angle < 135)
                {
                    character.RotateLeft();
                    Debug.Log("左转" + "    " + angle);
                }
                else if (angle > 0 && angle < 45)
                {
                    character.isJump = true;
                    Debug.Log("跳跃" + "    " + angle);
                }
                else if (angle > 135 && angle < 180)
                {
                    character.Slide();
                    Debug.Log("下蹲" + "    " + angle);
                }
            }
            else if (cosValueX == 0)
            {
                if (angle > 0)
                {
                    character.isJump = true;
                    Debug.Log("跳跃" + "    " + angle);
                }
                else
                {
                    character.Slide();
                    Debug.Log("下蹲" + "    " + angle);
                }
            }
            else
            {
                if (angle > 45 && angle < 135)
                {
                    character.RotateRight();
                    Debug.Log("右转" + "    " + angle);
                }
                else if (angle > 0 && angle < 45)
                {
                    character.isJump = true;
                    Debug.Log("跳跃" + "    " + angle);
                }
                else if (angle > 135 && angle < 180)
                {
                    character.Slide();
                    Debug.Log("下蹲" + "    " + angle);
                }
            }

            isInput = false;
        }
#endif
    }
Exemple #16
0
    private void Render()
    {
        MeshRenderer render = gameObject.GetComponent <MeshRenderer>();

        render.sharedMaterial = new Material(Shader.Find("Standard"));
        render.sharedMaterial.SetInt("_Metallic", 1);
        render.sharedMaterial.SetInt("_Glossiness", 0);
        MeshFilter filter = gameObject.GetComponent <MeshFilter>();
        Mesh       mesh   = new Mesh();

        filter.sharedMesh = mesh;
        mesh.Clear();
        mesh.name = gameObject.name;

        #region Vertices
        List <Vector3>         vertList = new List <Vector3>();
        Dictionary <long, int> middlePointIndexCache = new Dictionary <long, int>();

        // create 12 vertices of a icosahedron
        float t = (1f + Mathf.Sqrt(5f)) / 2f;

        vertList.Add(new Vector3(-1f, t, 0f).normalized *radius);
        vertList.Add(new Vector3(1f, t, 0f).normalized *radius);
        vertList.Add(new Vector3(-1f, -t, 0f).normalized *radius);
        vertList.Add(new Vector3(1f, -t, 0f).normalized *radius);

        vertList.Add(new Vector3(0f, -1f, t).normalized *radius);
        vertList.Add(new Vector3(0f, 1f, t).normalized *radius);
        vertList.Add(new Vector3(0f, -1f, -t).normalized *radius);
        vertList.Add(new Vector3(0f, 1f, -t).normalized *radius);

        vertList.Add(new Vector3(t, 0f, -1f).normalized *radius);
        vertList.Add(new Vector3(t, 0f, 1f).normalized *radius);
        vertList.Add(new Vector3(-t, 0f, -1f).normalized *radius);
        vertList.Add(new Vector3(-t, 0f, 1f).normalized *radius);
        #endregion

        #region Face
        // create 20 triangles of the icosahedron
        List <TriangleIndices> faces = new List <TriangleIndices>();

        // 5 faces around point 0
        faces.Add(new TriangleIndices(0, 11, 5));
        faces.Add(new TriangleIndices(0, 5, 1));
        faces.Add(new TriangleIndices(0, 1, 7));
        faces.Add(new TriangleIndices(0, 7, 10));
        faces.Add(new TriangleIndices(0, 10, 11));

        // 5 adjacent faces
        faces.Add(new TriangleIndices(1, 5, 9));
        faces.Add(new TriangleIndices(5, 11, 4));
        faces.Add(new TriangleIndices(11, 10, 2));
        faces.Add(new TriangleIndices(10, 7, 6));
        faces.Add(new TriangleIndices(7, 1, 8));

        // 5 faces around point 3
        faces.Add(new TriangleIndices(3, 9, 4));
        faces.Add(new TriangleIndices(3, 4, 2));
        faces.Add(new TriangleIndices(3, 2, 6));
        faces.Add(new TriangleIndices(3, 6, 8));
        faces.Add(new TriangleIndices(3, 8, 9));

        // 5 adjacent faces
        faces.Add(new TriangleIndices(4, 9, 5));
        faces.Add(new TriangleIndices(2, 4, 11));
        faces.Add(new TriangleIndices(6, 2, 10));
        faces.Add(new TriangleIndices(8, 6, 7));
        faces.Add(new TriangleIndices(9, 8, 1));


        #region Refine
        // refine triangles
        for (int i = 0; i < recursionLevel; i++)
        {
            List <TriangleIndices> faces2 = new List <TriangleIndices>();
            foreach (var tri in faces)
            {
                // 每個三角形再切成4個三角形
                int a = getMiddlePoint(tri.v1, tri.v2, ref vertList, ref middlePointIndexCache, radius);
                int b = getMiddlePoint(tri.v2, tri.v3, ref vertList, ref middlePointIndexCache, radius);
                int c = getMiddlePoint(tri.v3, tri.v1, ref vertList, ref middlePointIndexCache, radius);

                faces2.Add(new TriangleIndices(tri.v1, a, c));
                faces2.Add(new TriangleIndices(tri.v2, b, a));
                faces2.Add(new TriangleIndices(tri.v3, c, b));
                faces2.Add(new TriangleIndices(a, b, c));
            }
            faces = faces2;
        }
        #endregion


        mesh.vertices = vertList.ToArray();

        List <int> triList = new List <int>();
        for (int i = 0; i < faces.Count; i++)
        {
            triList.Add(faces[i].v1);
            triList.Add(faces[i].v2);
            triList.Add(faces[i].v3);
        }
        mesh.triangles = triList.ToArray();
        #endregion

        #region UVs
        var       nVertices = mesh.vertices;
        Vector2[] UVs       = new Vector2[nVertices.Length];

        for (var i = 0; i < nVertices.Length; i++)
        {
            var     unitVector = nVertices[i].normalized;
            Vector2 ICOuv      = new Vector2(0, 0);
            ICOuv.x = (Mathf.Atan2(unitVector.x, unitVector.z) + Mathf.PI) / Mathf.PI / 2;
            ICOuv.y = (Mathf.Acos(unitVector.y) + Mathf.PI) / Mathf.PI - 1;
            UVs[i]  = new Vector2(ICOuv.x, ICOuv.y);
        }

        mesh.uv = UVs;
        #endregion

        Vector3[] normales = new Vector3[vertList.Count];
        for (int i = 0; i < normales.Length; i++)
        {
            normales[i] = vertList[i].normalized;
        }

        mesh.normals = normales;
        mesh.RecalculateBounds();


        filter.sharedMesh = mesh;
        mesh.RecalculateBounds();
    }
Exemple #17
0
 public static float CosLaw(float a, float b, float c)
 {
     return(Mathf.Acos(Mathf.Clamp((Mathf.Pow(a, 2) + Mathf.Pow(b, 2.0f) - Mathf.Pow(c, 2.0f)) / (2.0f * a * b), -1.0f, 1.0f)) * Mathf.Rad2Deg);
 }
Exemple #18
0
    // Update is called once per frame
    void Update()
    {
        switch (KeyCheck())
        {
        case 'w':
            endX += 0.1f;
            if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) ||
                Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)))
            {
                Debug.Log("Out of range!");
                endX -= 0.1f;
            }
            break;

        case 's':
            endX -= 0.1f;
            if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) ||
                Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)))
            {
                Debug.Log("Out of range!");
                endX += 0.1f;
            }
            break;

        case 'a':
            endZ += 0.1f;
            if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) ||
                Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)))
            {
                Debug.Log("Out of range!");
                endZ -= 0.1f;
            }
            break;

        case 'd':
            endZ -= 0.1f;
            if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) ||
                Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)))
            {
                Debug.Log("Out of range!");
                endZ += 0.1f;
            }
            break;

        case 'r':
            endY += 0.1f;
            if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) ||
                Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)))
            {
                Debug.Log("Out of range!");
                endY -= 0.1f;
            }
            break;

        case 'f':
            endY -= 0.1f;
            if (Mathf.Pow(Link2 + Link3, 2) <= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) ||
                Mathf.Pow(Link2 - Link3, 2) + 0.1f >= (Mathf.Pow(endX, 2)) + (Mathf.Pow(endY - Link1 * 0.5f, 2)) + (Mathf.Pow(endZ, 2)) ||
                endY - 0.5f <= 0)
            {
                Debug.Log("Out of range!");
                endY += 0.1f;
            }
            break;
        }
        EC.transform.localPosition = new Vector3(endX, endY, endZ);

        /* 逆運動学による姿勢(角度)の計算 */
        LenA  = Mathf.Sqrt(endX * endX + endZ * endZ) /*endX / Mathf.Cos(Mathf.Atan2(endZ, endX))*/;
        LenB  = (endY - Link1 * 0.5f) * (-1);
        DegA  = Mathf.Acos((LenA * LenA + LenB * LenB - Link2 * Link2 - Link3 * Link3) / (2.0f * Link2 * Link3));
        DegB  = Mathf.Atan2(Link3 * Mathf.Sin(DegA), Link2 + Link3 * Mathf.Cos(DegA));
        DegJ1 = Mathf.Atan2(endZ, endX) * Mathf.Rad2Deg;
        DegJ2 = Mathf.Asin(LenB / Mathf.Sqrt(LenA * LenA + LenB * LenB) /*(LenA / Mathf.Cos(Mathf.Atan2(LenB, LenA)))*/) * Mathf.Rad2Deg - DegB * Mathf.Rad2Deg;
        DegJ3 = DegA * Mathf.Rad2Deg;

        //Debug.Log("J1 = " + DegJ1);
        //Debug.Log("J2 = " + DegJ2);
        //Debug.Log("J3 = " + DegJ3);

        /* 位置 */
        RadJ1   = DegJ1 * Mathf.Deg2Rad;
        RadJ2   = DegJ2 * Mathf.Deg2Rad;
        PosJ3.x = (Link2 * Mathf.Cos(RadJ2)) * Mathf.Cos(RadJ1);
        PosJ3.y = (Link2 * Mathf.Sin(RadJ2 * (-1))) + Link1 * 0.5f;
        PosJ3.z = (Link2 * Mathf.Cos(RadJ2)) * Mathf.Sin(RadJ1);
        J3.transform.localPosition = PosJ3;

        /* 姿勢 */
        J1.transform.eulerAngles = new Vector3(0, DegJ1 * (-1), 0);
        J2.transform.eulerAngles = new Vector3(DegJ2 * (-1), DegJ1 * (-1) + (-90), 90);
        J3.transform.eulerAngles = new Vector3((DegJ2 + DegJ3) * (-1), DegJ1 * (-1) + (-90), 90);
        EC.transform.eulerAngles = new Vector3(0, DegJ1 * (-1), (DegJ2 + DegJ3) * (-1));
    }
    void Update()
    {
        //Change nolovrmanager's rotation
        //Double controller press the grip button at the same time
        if (NoloVR_Controller.GetDevice(NoloDeviceType.LeftController).GetNoloButtonPressed(NoloButtonID.Grip) &&
            NoloVR_Controller.GetDevice(NoloDeviceType.RightController).GetNoloButtonPressed(NoloButtonID.Grip))
        {
            //Record the middle of the two controller
            controllerCenter.transform.position = new Vector3((rightController.position.x + leftController.position.x) / 2,
                                                              (rightController.position.y + leftController.position.y) / 2,
                                                              (rightController.position.z + leftController.position.z) / 2);
            //Set the parent of the sence object
            objectParents.SetParent(controllerCenter.transform);

            //Change scale
            if (isChangeScale)
            {
                distance = Vector3.Distance(leftController.position, rightController.position);
                if (originDistance < 0)
                {
                    originDistance = distance;
                }
                scaling = preScaling + distance - originDistance;
                //Min scale 0.1
                if (scaling < 0.1f)
                {
                    scaling = 0.1f;
                }
                controllerCenter.transform.localScale = new Vector3(scaling, scaling, scaling);
            }

            //Change rotation
            if (isChangeRotation)
            {
                vetor = new Vector3(rightController.localPosition.x - leftController.localPosition.x, 0, rightController.localPosition.z - leftController.localPosition.z);
                if (preVetor == Vector3.zero)
                {
                    preVetor = vetor;
                }
                float angle = Mathf.Acos(Vector3.Dot(preVetor.normalized, vetor.normalized)) * Mathf.Rad2Deg;
                //Max rotation angle
                if (angle > maxAngel)
                {
                    return;
                }
                //Filter illegal numbers
                if (float.IsNaN(angle))
                {
                    return;
                }
                if (rightController.localPosition.z - leftController.localPosition.z - preVetor.z > 0)
                {
                    angle = -angle;
                }
                controllerCenter.transform.rotation = Quaternion.Euler(prerotation + new Vector3(0, angle, 0));
            }
        }
        else
        {
            objectParents.SetParent(null);
            originDistance = -1;
            preScaling     = controllerCenter.transform.localScale.x;
            preVetor       = Vector3.zero;
            prerotation    = controllerCenter.transform.localRotation.eulerAngles;
        }
    }
    Mesh _CreateMesh()
    {
        Mesh mesh = new Mesh();

        int hvCount2     = this.segments + 1;
        int hvCount2Half = hvCount2 / 2;
        int numVertices  = hvCount2 * hvCount2;
        int numTriangles = this.segments * this.segments * 6;

        Vector3[] vertices  = new Vector3[numVertices];
        Vector2[] uvs       = new Vector2[numVertices];
        int[]     triangles = new int[numTriangles];

        float scaleFactor = 2.0f / (float)this.segments;
        float uvFactor    = 1.0f / (float)this.segments;

        if (this.segments <= 1 || this.shape == Shape.Cube)
        {
            float ty = 0.0f, py = -1.0f;
            int   index = 0;
            for (int y = 0; y < hvCount2; ++y, ty += uvFactor, py += scaleFactor)
            {
                float tx = 0.0f, px = -1.0f;
                for (int x = 0; x < hvCount2; ++x, ++index, tx += uvFactor, px += scaleFactor)
                {
                    vertices[index] = new Vector3(px, py, 1.0f);
                    uvs[index]      = new Vector2(tx, ty);
                }
            }
        }
        else
        {
            float ty = 0.0f, py = -1.0f;
            int   index = 0, indexY = 0;
            for (int y = 0; y <= hvCount2Half; ++y, indexY += hvCount2, ty += uvFactor, py += scaleFactor)
            {
                float tx = 0.0f, px = -1.0f, py2 = py * py;
                int   x = 0;
                for ( ; x <= hvCount2Half; ++x, ++index, tx += uvFactor, px += scaleFactor)
                {
                    float d        = Mathf.Sqrt(px * px + py2 + 1.0f);
                    float theta    = Mathf.Acos(1.0f / d);
                    float phi      = Mathf.Atan2(py, px);
                    float sinTheta = Mathf.Sin(theta);
                    vertices[index] = new Vector3(
                        sinTheta * Mathf.Cos(phi),
                        sinTheta * Mathf.Sin(phi),
                        Mathf.Cos(theta));
                    uvs[index] = new Vector2(tx, ty);
                }
                int indexX = hvCount2Half - 1;
                for ( ; x < hvCount2; ++x, ++index, --indexX, tx += uvFactor, px += scaleFactor)
                {
                    Vector3 v = vertices[indexY + indexX];
                    vertices[index] = new Vector3(-v.x, v.y, v.z);
                    uvs[index]      = new Vector2(tx, ty);
                }
            }
            indexY = (hvCount2Half - 1) * hvCount2;
            for (int y = hvCount2Half + 1; y < hvCount2; ++y, indexY -= hvCount2, ty += uvFactor, py += scaleFactor)
            {
                float tx = 0.0f, px = -1.0f;
                int   x = 0;
                for ( ; x <= hvCount2Half; ++x, ++index, tx += uvFactor, px += scaleFactor)
                {
                    Vector3 v = vertices[indexY + x];
                    vertices[index] = new Vector3(v.x, -v.y, v.z);
                    uvs[index]      = new Vector2(tx, ty);
                }
                int indexX = hvCount2Half - 1;
                for ( ; x < hvCount2; ++x, ++index, --indexX, tx += uvFactor, px += scaleFactor)
                {
                    Vector3 v = vertices[indexY + indexX];
                    vertices[index] = new Vector3(-v.x, -v.y, v.z);
                    uvs[index]      = new Vector2(tx, ty);
                }
            }
        }

        {
            for (int y = 0, index = 0, ofst = 0; y < this.segments; ++y, ofst += hvCount2)
            {
                int y0 = ofst, y1 = ofst + hvCount2;
                for (int x = 0; x < this.segments; ++x, index += 6)
                {
                    triangles[index + 0] = y0 + x;
                    triangles[index + 1] = y1 + x;
                    triangles[index + 2] = y0 + x + 1;
                    triangles[index + 3] = y1 + x;
                    triangles[index + 4] = y1 + x + 1;
                    triangles[index + 5] = y0 + x + 1;
                }
            }
        }

        mesh.vertices  = vertices;
        mesh.uv        = uvs;
        mesh.triangles = triangles;
        return(mesh);
    }
        protected void OwnerToTargetAngle()
        {
            var diff = owner.position - target.position;

            Debug.LogFormat("XY Angle is {0}", Mathf.Acos(diff.y / diff.x) * Mathf.Rad2Deg);
        }
Exemple #22
0

        
Exemple #23
0
 public static float AngleBetween(Vector3 a, Vector3 b)
 {
     return(Mathf.Acos(Vector3.Dot(a, b) / (a.magnitude * b.magnitude)) * MathUtil.RAD_TO_DEG);
 }
Exemple #24
0
    public static void makeTacticUpdate()
    {
        if (b > 1)
        {
            mainStatic.regiment_stat[0].countTypes();
            mainStatic.regiment_stat[0].typeSpecification = 0;
            mainStatic.regiment_stat[0].rebuilding(2);
            mainStatic.updateRegimentPosition(0);

            b = 0;
        }
        else
        {
            for (int i = 0; i < mainStatic.regiment_stat.Count; i++)
            {
                for (int r = 0; r < mainStatic.regiment_stat[i].officers.Count; r++)
                {
                    OfficerStatement.MakeOfficerStatement(i, r);
                }
            }
        }
        // Очищаем массив со смертями на всяк пожарный
        DeadBuff.Delete();
        ArrowBuff.Delete();

        // счетчик смерти на 0
        mainStatic.deathcount = 0;

        // Удаляем пустые места от убитых солдат + проверка на стойкость
        for (int i = 0; i < mainStatic.regiment_stat.Count; i++)
        {
            int t = 0;
            while (t < mainStatic.regiment_stat[i].soldiers.Count)
            {
                if (mainStatic.regiment_stat[i].soldiers[t] == null)
                {
                    mainStatic.regiment_stat[i].soldiers.RemoveAt(t);
                }
                else
                {
                    t++;
                }
            }

            for (int j = 0; j < mainStatic.regiment_stat[i].soldiers.Count; j++)
            {
                mainStatic.regiment_stat[i].soldiers[j].numSoldier = j;
            }


            //// Все драки прекращаются.
            //mainStatic.regiment_stat[i].stateFighting = false;

            /* Debug.Log("ST");
             * Debug.Log(mainStatic.regiment_stat[i].soldier_count);
             * Debug.Log(mainStatic.regiment_stat[i].prim_soldier_count);
             */
            /// Прохождение теста на панику
            if (mainStatic.regiment_stat[i].soldier_count < (mainStatic.regiment_stat[i].prim_soldier_count / 2))
            {
                mainStatic.regiment_stat[i].statePanic    = true;
                mainStatic.regiment_stat[i].stateFighting = false;
                Debug.Log("PANIC");

                // В какую сторону побежит?
                // Направление в которое побежит
                Vector3 PanicTarget = new Vector3(0, 0, 0);

                for (int s = 0; s < mainStatic.regiment_stat[i].figthMas.Count; s++)
                {
                    if (mainStatic.regiment_stat[mainStatic.regiment_stat[i].figthMas[s]].command != mainStatic.regiment_stat[i].command)
                    {
                        //Debug.Log(PanicTarget);
                        PanicTarget += (mainStatic.regiment_stat[i].regPosition - mainStatic.regiment_stat[mainStatic.regiment_stat[i].figthMas[s]].regPosition).normalized;
                    }
                }
                PanicTarget = PanicTarget.normalized;
                //Debug.Log(PanicTarget);
                float x = PanicTarget.x; float y = PanicTarget.y; float z = PanicTarget.z;

                // Считаем угол между двумя векторами
                if (x >= 0 && z >= 0)
                {
                    mainStatic.regiment_stat[i].angle = Mathf.Acos(z) + 3.1415f / 2;
                }
                if (x > 0 && z < 0)
                {
                    mainStatic.regiment_stat[i].angle = -Mathf.Acos(z) + 3.1415f + 3.1415f / 2;
                }
                if (x <= 0 && z <= 0)
                {
                    mainStatic.regiment_stat[i].angle = Mathf.Acos(z) + 3.1415f + 3.1415f / 2;
                }
                if (x < 0 && z > 0)
                {
                    mainStatic.regiment_stat[i].angle = -Mathf.Acos(-z) + 3.1415f * 2 + 3.1415f / 2;
                }
            }
            if (mainStatic.regiment_stat[i].statePanic == true)
            {
                mainStatic.makeRegimentMove(i, 6.0f);
                mainStatic.updateRegimentPosition(i);
            }

            for (int h = 0; h < mainStatic.regiment_stat.Count; h++)
            {
                mainStatic.regiment_stat[h].figthMas.Clear();
            }
            //mainStatic.regiment_stat[i].figthMas.Clear();
        }

        UpdateEnReg();

        mainStatic.addMeshForBattle();
        mainStatic.dellMeshForBattle();

        // Формируем в каждом полку fightMas в котором содержатся номера полков, которые участвуют с ним в одной схватке
        // Для кажого списка
        for (int y = 0; y < mainStatic.regiment_stat.Count; y++)
        {
            mainStatic.regiment_stat[y].figthMas.Clear();
        }

        for (int y = 0; y < mainStatic.listFigReg.Count; y++)
        {
            // Для каждого элемента в списке одной схватке
            for (int r = 0; r < mainStatic.listFigReg[y].M.Count; r++)
            {
                // Сравнить с каждым другим
                for (int w = 0; w < mainStatic.listFigReg[y].M.Count; w++)
                {
                    if (r != w)
                    {
                        mainStatic.regiment_stat[mainStatic.listFigReg[y].M[r]].
                        figthMas.Add(mainStatic.listFigReg[y].M[w]);
                    }
                }
            }
        }


        /// Раздел в котором добавляем точки для навигации солдат во время боя
        /// Каждый период если полк сражается

        for (int t = 0; t < mainStatic.regiment_stat.Count; t++)
        {
            if (mainStatic.regiment_stat[t].stateFighting == true)
            {
                for (int i = 0; i < mainStatic.regiment_stat[t].figthMas.Count; i++)
                {
                    if (mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].command != mainStatic.regiment_stat[t].command)
                    {
                        mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].make_position();
                        mainStatic.regiment_stat[t].targPos.Clear();

                        Vector3 v3 = new Vector3(0, 0, 0);
                        /// Для клина и каре отдельно!
                        if (mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regFirstLine < 6 && mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regLastLine < 8)
                        {
                            v3 = mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[0]
                                 + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[1]
                                 + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[2]
                                 + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[3];
                            v3 = v3 / 4;

                            if (mainStatic.regiment_stat[t].command == 1)
                            {
                                Debug.Log("HUD");
                            }
                            mainStatic.regiment_stat[t].targPos.Add(v3);
                        }
                        else
                        {
                            Vector3 v5 = mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[0]
                                         + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[1]
                                         + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[2]
                                         + mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[3];
                            v5 /= 4;
                            mainStatic.regiment_stat[t].targPos.Add(v5);

                            /// Сдвигаемся на 6 в сторону, если там есть солдат,
                            bool  fl = true;
                            float j  = 6;
                            while (fl == true)
                            {
                                if (j < mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regFirstLine / 2)
                                {
                                    v3 = v5 + j * mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regDistanseLine * (mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[1] - mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[0]).normalized;
                                    mainStatic.regiment_stat[t].targPos.Add(v3);
                                    v3 = v5 - j * mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].regDistanseLine * (mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[1] - mainStatic.regiment_stat[mainStatic.regiment_stat[t].figthMas[i]].Position_Reg[0]).normalized;
                                    mainStatic.regiment_stat[t].targPos.Add(v3);

                                    if (mainStatic.regiment_stat[t].command == 1)
                                    {
                                        Debug.Log("HUD2");
                                    }
                                    j += 6;
                                }
                                else
                                {
                                    fl = false;
                                }
                            }
                        }
                    }
                }
            }
        }



        // Найти сражающиеся полки и для каждого солдата участника вызвать атаку
        for (int t = 0; t < mainStatic.regiment_stat.Count; t++)
        {
            if (mainStatic.regiment_stat[t].stateFighting == true)
            {
                for (int r = 0; r < mainStatic.regiment_stat[t].soldiers.Count; r++)
                {
                    mainStatic.regiment_stat[t].soldiers[r].at();
                }
            }
        }

        // Сортируем смерти по времени исполения
        DeadBuff.mySort();

        // Сортируем стрелы по времени
        ArrowBuff.mySort();

        // Удалим повторяющиеся
        mainStatic.t0 = Time.time;

        for (int t = 0; t < mainStatic.regiment_stat.Count; t++)
        {
            if (mainStatic.regiment_stat[t].stateFighting == false)
            {
                if (mainStatic.regiment_stat[t].orderForw == true)
                {
                    mainStatic.makeRegimentMove(t, 1.0f);
                    mainStatic.updateRegimentPosition(t);
                    mainStatic.regiment_stat[t].orderForw = false;
                }

                if (mainStatic.regiment_stat[t].orderBack == true)
                {
                    mainStatic.makeRegimentMove(t, -1.0f);
                    mainStatic.updateRegimentPosition(t);
                    mainStatic.regiment_stat[t].orderBack = false;
                }

                if (mainStatic.regiment_stat[t].orderRotW == true)
                {
                    mainStatic.makeRegimentRotation(t, +.3f);
                    mainStatic.updateRegimentPosition(t);
                    mainStatic.regiment_stat[t].orderRotW   = false;
                    mainStatic.regiment_stat[t].delta_angle = 0;
                }
                if (mainStatic.regiment_stat[t].orderRotL == true)
                {
                    mainStatic.makeRegimentRotation(t, -.3f);
                    mainStatic.updateRegimentPosition(t);
                    mainStatic.regiment_stat[t].orderRotL   = false;
                    mainStatic.regiment_stat[t].delta_angle = 0;
                }
                if (mainStatic.regiment_stat[t].archTotewer == true)
                {
                    mainStatic.regiment_stat[t].archerAt(t, TactUpdate.nearestReg(t), true);
                    mainStatic.regiment_stat[t].archTotewer = false;
                }
                if (mainStatic.regiment_stat[t].archAlone == true)
                {
                    mainStatic.regiment_stat[t].archerAt(t, TactUpdate.nearestReg(t), false);
                    mainStatic.regiment_stat[t].archAlone = false;
                }
            }
        }
    }
Exemple #25
0
        public void UpdateBoneTransform(int index)
        {
            var image = BoneImages[index];

            image.TotalRotation    = image.MorphRotation * image.Rotation;
            image.TotalTranslation = image.MorphTranslation + image.Translation;

            if (image.HasAppend)
            {
                if (image.AppendRotate)
                {
                    image.TotalRotation = image.TotalRotation *
                                          Quaternion.Slerp(Quaternion.identity,
                                                           BoneImages[image.AppendParent].TotalRotation, image.AppendRatio);
                }
                if (image.AppendTranslate)
                {
                    image.TotalTranslation = image.TotalTranslation +
                                             image.AppendRatio * BoneImages[image.AppendParent].TotalTranslation;
                }
            }

            if (image.IkLink)
            {
                image.PreIkRotation = image.TotalRotation;
                image.TotalRotation = image.IkRotation * image.TotalRotation;
            }

            image.LocalMatrix = MathUtil.QuaternionToMatrix4X4(image.TotalRotation);
            MathUtil.SetTransToMatrix4X4(image.TotalTranslation + image.LocalOffset, ref image.LocalMatrix);

            if (image.HasParent)
            {
                image.LocalMatrix = BoneImages[image.Parent].LocalMatrix * image.LocalMatrix;
            }

            if (!image.HasIk)
            {
                return;
            }
            var ikLinkNum = image.IkLinks.Length;

            for (var i = 0; i < ikLinkNum; ++i)
            {
                BoneImages[image.IkLinks[i]].IkRotation = Quaternion.identity;
            }
            var ikPosition = MathUtil.GetTransFromMatrix4X4(image.LocalMatrix);

            for (var i = 0; i < ikLinkNum; ++i)
            {
                UpdateBoneTransform(image.IkTarget);
            }
            var targetPosition = MathUtil.GetTransFromMatrix4X4(BoneImages[image.IkTarget].LocalMatrix);
            var ikError        = ikPosition - targetPosition;

            if (Vector3.Dot(ikError, ikError) < Tools.MmdMathConstEps)
            {
                return;
            }
            var ikt = image.CcdIterateLimit / 2;

            for (var i = 0; i < image.CcdIterateLimit; ++i)
            {
                for (var j = 0; j < ikLinkNum; ++j)
                {
                    if (image.IkFixTypes[j] == BoneImage.AxisFixType.FixAll)
                    {
                        continue;
                    }
                    var ikImage         = BoneImages[image.IkLinks[j]];
                    var ikLinkPosition  = MathUtil.GetTransFromMatrix4X4(ikImage.LocalMatrix);
                    var targetDirection = ikLinkPosition - targetPosition;
                    var ikDirection     = ikLinkPosition - ikPosition;

                    targetDirection.Normalize();
                    ikDirection.Normalize();

                    var ikRotateAxis = Vector3.Cross(targetDirection, ikDirection);
                    for (var k = 0; k < 3; ++k)
                    {
                        if (Math.Abs(ikRotateAxis[k]) < Tools.MmdMathConstEps)
                        {
                            ikRotateAxis[k] = Tools.MmdMathConstEps;
                        }
                    }
                    var localizationMatrix = ikImage.HasParent ? BoneImages[ikImage.Parent].LocalMatrix : Matrix4x4.identity;
                    if (image.IkLinkLimited[j] && image.IkFixTypes[j] != BoneImage.AxisFixType.FixNone &&
                        i < ikt)
                    {
                        switch (image.IkFixTypes[j])
                        {
                        case BoneImage.AxisFixType.FixX:
                            ikRotateAxis.x =
                                Nabs(Vector3.Dot(ikRotateAxis,
                                                 MathUtil.Matrix4x4ColDowngrade(localizationMatrix, 0)));
                            ikRotateAxis.y = ikRotateAxis.z = 0.0f;
                            break;

                        case BoneImage.AxisFixType.FixY:
                            ikRotateAxis.y =
                                Nabs(Vector3.Dot(ikRotateAxis,
                                                 MathUtil.Matrix4x4ColDowngrade(localizationMatrix, 1)));
                            ikRotateAxis.x = ikRotateAxis.z = 0.0f;
                            break;

                        case BoneImage.AxisFixType.FixZ:
                            ikRotateAxis.z =
                                Nabs(Vector3.Dot(ikRotateAxis,
                                                 MathUtil.Matrix4x4ColDowngrade(localizationMatrix, 2)));
                            ikRotateAxis.x = ikRotateAxis.y = 0.0f;
                            break;
                        }
                    }
                    else
                    {
                        ikRotateAxis = Matrix4x4.Transpose(localizationMatrix).MultiplyVector(ikRotateAxis);
                        ikRotateAxis.Normalize();
                    }
                    var ikRotateAngle =
                        Mathf.Min(Mathf.Acos(Mathf.Clamp(Vector3.Dot(targetDirection, ikDirection), -1.0f, 1.0f)),
                                  image.CcdAngleLimit * (j + 1));
                    ikImage.IkRotation =
                        Quaternion.AngleAxis((float)(ikRotateAngle / Math.PI * 180.0), ikRotateAxis) * ikImage.IkRotation;
                    if (image.IkLinkLimited[j])
                    {
                        var localRotation = ikImage.IkRotation * ikImage.PreIkRotation;
                        switch (image.IkTransformOrders[j])
                        {
                        case BoneImage.AxisTransformOrder.OrderZxy:
                        {
                            var eularAngle = MathUtil.QuaternionToZxy(localRotation);
                            eularAngle = LimitEularAngle(eularAngle, image.IkLinkLimitsMin[j],
                                                         image.IkLinkLimitsMax[j], i < ikt);
                            localRotation = MathUtil.ZxyToQuaternion(eularAngle);
                            break;
                        }

                        case BoneImage.AxisTransformOrder.OrderXyz:
                        {
                            var eularAngle = MathUtil.QuaternionToXyz(localRotation);
                            eularAngle = LimitEularAngle(eularAngle, image.IkLinkLimitsMin[j],
                                                         image.IkLinkLimitsMax[j], i < ikt);
                            localRotation = MathUtil.XyzToQuaternion(eularAngle);
                            break;
                        }

                        case BoneImage.AxisTransformOrder.OrderYzx:
                        {
                            var eularAngle = MathUtil.QuaternionToYzx(localRotation);
                            eularAngle = LimitEularAngle(eularAngle, image.IkLinkLimitsMin[j],
                                                         image.IkLinkLimitsMax[j], i < ikt);
                            localRotation = MathUtil.YzxToQuaternion(eularAngle);
                            break;
                        }

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                        ikImage.IkRotation = localRotation * Quaternion.Inverse(image.PreIkRotation);
                    }
                    for (var k = 0; k <= j; ++k)
                    {
                        var linkImage = BoneImages[image.IkLinks[j - k]];
                        linkImage.TotalRotation = linkImage.IkRotation * linkImage.PreIkRotation;
                        linkImage.LocalMatrix   = MathUtil.QuaternionToMatrix4X4(linkImage.TotalRotation);
                        MathUtil.SetTransToMatrix4X4(linkImage.TotalTranslation + linkImage.LocalOffset,
                                                     ref linkImage.LocalMatrix);
                        if (linkImage.HasParent)
                        {
                            linkImage.LocalMatrix =
                                BoneImages[linkImage.Parent].LocalMatrix * linkImage.LocalMatrix;
                        }
                    }
                    UpdateBoneTransform(image.IkTarget);
                    targetPosition = MathUtil.Matrix4x4ColDowngrade(BoneImages[image.IkTarget].LocalMatrix, 3);
                }
                ikError = ikPosition - targetPosition;
                if (Vector3.Dot(ikError, ikError) < Tools.MmdMathConstEps)
                {
                    return;
                }
            }
        }
Exemple #26
0
    void WaitRaycast()
    {
        if (Physics.Raycast(ray, out hit, rayLength, sunMask))
        {
            Debug.Log("검출하였습니다.");

            //시계UI 고정
            if (transform != null)
            {
                transform.parent = transform.parent.parent; // 부모로부터 상속해제 후 부모와 동일

                //transform.rotation = Quaternion.Euler(0, target., 0);
                //transform.rotation = Quaternion.identity; // 로테이션값 초기화
                transform.eulerAngles = new Vector3(-93, transform.eulerAngles.y, transform.eulerAngles.z); //태양 방향의 값으로 평면화

                /*rb.constraints = RigidbodyConstraints.FreezeRotationX;
                *  rb.constraints = RigidbodyConstraints.FreezeRotationY;
                *  rb.constraints = RigidbodyConstraints.FreezeRotationZ;
                *  rb.constraints = RigidbodyConstraints.FreezePositionY;*/
            }
            target.GetComponent <Collider>().enabled = false;

            SN = SliderNumber.Slider_R;
            //빨간색화살표 생성
            m_ArrowSlider[1].gameObject.SetActive(true);
            currTime = 0;


            m_ArrowSlider[2].gameObject.SetActive(true);
            //SN = SliderNumber.Slider_B;

            //emptyPivot.localRotation = Quaternion.LookRotation(mid);

            //ok = true;

            float Dot    = Vector3.Dot(handPivot.up, bigWatch.forward);
            float angle2 = Mathf.Acos(Dot) * Mathf.Rad2Deg;
            //6시 일 때 남쪽은 6시
            if (angle == 6 || angle == 12)
            {
                emptyPivot.localEulerAngles = handPivot.localEulerAngles;
            }

            /*//12시 일 때 남쪽은 12시
             * else if(angle == 12)
             * {
             *  emptyPivot.localEulerAngles = Vector3.back;
             * }*/
            else if (angle > 6 && angle < 12)
            {
                emptyPivot.localEulerAngles = new Vector3(0, 0, -angle2 / 2);
            }
            else
            {
                emptyPivot.localEulerAngles = new Vector3(0, 0, angle2 / 2);
            }

            Destroy(gameObject, 3f);

            //finalCanvas.SetActive(true);
        }
    }
    public void CreateIcosphere()
    {
        // create 12 vertices of a icosahedron
        var t = (1.0f + Mathf.Sqrt(5.0f)) / 2.0f;

        AddVertex(new Vector3(-1, t, 0));
        AddVertex(new Vector3(1, t, 0));
        AddVertex(new Vector3(-1, -t, 0));
        AddVertex(new Vector3(1, -t, 0));

        AddVertex(new Vector3(0, -1, t));
        AddVertex(new Vector3(0, 1, t));
        AddVertex(new Vector3(0, -1, -t));
        AddVertex(new Vector3(0, 1, -t));

        AddVertex(new Vector3(t, 0, -1));
        AddVertex(new Vector3(t, 0, 1));
        AddVertex(new Vector3(-t, 0, -1));
        AddVertex(new Vector3(-t, 0, 1));

        // create 20 triangles of the icosahedron
        faces = new List <TriangleIndices>();

        // 5 faces around point 0
        faces.Add(new TriangleIndices(0, 11, 5));
        faces.Add(new TriangleIndices(0, 5, 1));
        faces.Add(new TriangleIndices(0, 1, 7));
        faces.Add(new TriangleIndices(0, 7, 10));
        faces.Add(new TriangleIndices(0, 10, 11));

        // 5 adjacent faces
        faces.Add(new TriangleIndices(1, 5, 9));
        faces.Add(new TriangleIndices(5, 11, 4));
        faces.Add(new TriangleIndices(11, 10, 2));
        faces.Add(new TriangleIndices(10, 7, 6));
        faces.Add(new TriangleIndices(7, 1, 8));

        // 5 faces around point 3
        faces.Add(new TriangleIndices(3, 9, 4));
        faces.Add(new TriangleIndices(3, 4, 2));
        faces.Add(new TriangleIndices(3, 2, 6));
        faces.Add(new TriangleIndices(3, 6, 8));
        faces.Add(new TriangleIndices(3, 8, 9));

        // 5 adjacent faces
        faces.Add(new TriangleIndices(4, 9, 5));
        faces.Add(new TriangleIndices(2, 4, 11));
        faces.Add(new TriangleIndices(6, 2, 10));
        faces.Add(new TriangleIndices(8, 6, 7));
        faces.Add(new TriangleIndices(9, 8, 1));

        Subdivide(Subdivisions);
        // done, now add triangles to mesh
        foreach (var tri in faces)
        {
            indices.Add(tri.v3);
            indices.Add(tri.v2);
            indices.Add(tri.v1);
        }

        List <Vector2> UVs = new List <Vector2>();

        foreach (var v in verts)
        {
            var unitVector = v.Normalized();
            var ICOuv      = Vector2.Zero;
            ICOuv.x = (Mathf.Atan2(unitVector.x, unitVector.z) + Mathf.Pi) / Mathf.Pi / 2;
            ICOuv.y = (Mathf.Acos(unitVector.y) + Mathf.Pi) / Mathf.Pi - 1;
            UVs.Add(new Vector2(ICOuv.x, ICOuv.y));
        }
        uvs = UVs;
    }
Exemple #28
0
    public static int[] Triangulate(Vector2z[] points)
    {
        int        numberOfPoints = points.Length;
        List <int> usePoints      = new List <int>();

        for (int p = 0; p < numberOfPoints; p++)
        {
            usePoints.Add(p);
        }
        int        numberOfUsablePoints = usePoints.Count;
        List <int> indices = new List <int>();

        if (numberOfPoints < 3)
        {
            return(indices.ToArray());
        }

        int it = 100;

        while (numberOfUsablePoints > 3)
        {
            for (int i = 0; i < numberOfUsablePoints; i++)
            {
                int a, b, c;

                a = usePoints[i];

                if (i >= numberOfUsablePoints - 1)
                {
                    b = usePoints[0];
                }
                else
                {
                    b = usePoints[i + 1];
                }

                if (i >= numberOfUsablePoints - 2)
                {
                    c = usePoints[(i + 2) - numberOfUsablePoints];
                }
                else
                {
                    c = usePoints[i + 2];
                }

                Vector2 pA = points[b].vector2;
                Vector2 pB = points[a].vector2;
                Vector2 pC = points[c].vector2;

                float dA = Vector2.Distance(pA, pB);
                float dB = Vector2.Distance(pB, pC);
                float dC = Vector2.Distance(pC, pA);

                float angle = Mathf.Acos((Mathf.Pow(dB, 2) - Mathf.Pow(dA, 2) - Mathf.Pow(dC, 2)) / (2 * dA * dC)) * Mathf.Rad2Deg * Mathf.Sign(Sign(points[a], points[b], points[c]));
                if (angle < 0)
                {
                    continue;//angle is not reflex
                }

                bool freeOfIntersections = true;
                for (int p = 0; p < numberOfUsablePoints; p++)
                {
                    int pu = usePoints[p];
                    if (pu == a || pu == b || pu == c)
                    {
                        continue;
                    }

                    if (IntersectsTriangle2(points[a], points[b], points[c], points[pu]))
                    {
                        freeOfIntersections = false;
                        break;
                    }
                }

                if (freeOfIntersections)
                {
                    indices.Add(a);
                    indices.Add(b);
                    indices.Add(c);
                    usePoints.Remove(b);
                    it = 100;
                    numberOfUsablePoints = usePoints.Count;
                    i--;
                    break;
                }
            }
            it--;
            if (it < 0)
            {
                break;
            }
        }

        indices.Add(usePoints[0]);
        indices.Add(usePoints[1]);
        indices.Add(usePoints[2]);
        indices.Reverse();

        return(indices.ToArray());
    }
    public override void Fill()
    {
        if (scatterTexture == null && texturecollider == null)
        {
            return;
        }

        if (layers.Count == 0)
        {
            return;
        }

        if (update)
        {
            objcount     = 0;
            vertcount    = 0;
            scattercount = 0;

            Init();
            update = false;
            float totalweight = 0.0f;

            for (int i = 0; i < layers.Count; i++)
            {
                if (layers[i].Enabled)
                {
                    totalweight = layers[i].Init(totalweight);
                }
            }

            instances.Clear();                  // May not be right place

            totalarea = scatterLength * scatterWidth;
            int fullcount = (int)(totalarea * Density);
            if (countmode == MegaScatterMode.Count)
            {
                fullcount = forcecount;
            }

            for (int m = 0; m < layers.Count; m++)
            {
                if (layers[m].Enabled)
                {
                    int meshcount = (int)(fullcount * (layers[m].weight / totalweight));

                    if (!layers[m].perCurveCount)
                    {
                        if (layers[m].forcecount != 0)
                        {
                            meshcount = layers[m].forcecount;
                        }

                        if (layers[m].maxcount != 0 && meshcount > layers[m].maxcount)
                        {
                            meshcount = layers[m].maxcount;
                        }
                    }

                    float val = 0.0f;

                    //Random.seed = layers[m].seed + m;

                    if (!meshPerShape)
                    {
                        ClearMesh(layers[m].subcount);
                    }

                    // Do this if want overlap only for each mesh
                    if (layers[m].clearOverlap)
                    {
                        instances.Clear();                              // May not be right place
                    }
#if UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_6
                    Random.InitState(seed + layers[m].seed + m);
#else
                    Random.seed = seed + layers[m].seed + m;
#endif
                    for (int s = 0; s < layers[m].scattercols.Count; s++)
                    {
                        if (meshPerShape)
                        {
                            ClearMesh(layers[m].subcount);
                        }

                        int count = meshcount / layers[m].scattercols.Count;                            // * (curves[s].area / totalarea));

                        if (layers[m].perCurveCount)
                        {
                            if (layers[m].forcecount != 0)
                            {
                                count = layers[m].forcecount;
                            }

                            if (layers[m].maxcount != 0 && count > layers[m].maxcount)
                            {
                                count = layers[m].maxcount;
                            }
                        }

                        Vector3 p = Vector3.zero;

                        int failcount = FailCount;

                        for (int i = 0; i < count; i++)
                        {
                            float r1 = Random.value;
                            float r2 = Random.value;
                            float r3 = Random.value;
                            float r4 = Random.value;
                            float r5 = Random.value;
                            float r6 = Random.value;
                            float r7 = Random.value;
                            float r8 = Random.value;
                            float r9 = Random.value;
                            float rc = Random.value;

                            float alpha  = Mathf.Clamp01(layers[m].distCrv.Evaluate(r1));
                            float alpha1 = 0.0f;
                            float alpha2 = 0.0f;

                            Vector3 scl = Vector3.one;

                            if (layers[m].uniformScaling)
                            {
                                Vector3 low  = globalScale * layers[m].uniscaleLow;
                                Vector3 high = globalScale * layers[m].uniscaleHigh;
                                //scl = (low + (alpha * (high - low))) * 1.0f * (layers[m].scale);

                                switch (layers[m].uniscalemode)
                                {
                                case MegaScatterScaleMode.XYZ:
                                    scl = (low + (alpha * (high - low))) * 1.0f * (layers[m].scale);
                                    break;

                                case MegaScatterScaleMode.XY:
                                    scl.y = scl.x = (low.x + (alpha * (high.x - low.x))) * 1.0f * (layers[m].scale);
                                    scl.z = (low.z + (alpha1 * (high.z - low.z))) * 1.0f * (layers[m].scale);
                                    break;

                                case MegaScatterScaleMode.XZ:
                                    scl.z = scl.x = (low.x + (alpha * (high.x - low.x))) * 1.0f * (layers[m].scale);
                                    scl.y = (low.y + (alpha1 * (high.y - low.y))) * 1.0f * (layers[m].scale);
                                    break;

                                case MegaScatterScaleMode.YZ:
                                    scl.y = scl.z = (low.x + (alpha * (high.x - low.x))) * 1.0f * (layers[m].scale);
                                    scl.x = (low.x + (alpha1 * (high.x - low.x))) * 1.0f * (layers[m].scale);
                                    break;
                                }
                            }
                            else
                            {
                                alpha1 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r2));
                                alpha2 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r3));

                                Vector3 low  = Vector3.Scale(globalScale, layers[m].scaleLow);
                                Vector3 high = Vector3.Scale(globalScale, layers[m].scaleHigh);
                                scl.x = (low.x + (alpha * (high.x - low.x))) * 1.0f * (layers[m].scale);
                                scl.y = (low.y + (alpha1 * (high.y - low.y))) * 1.0f * (layers[m].scale);
                                scl.z = (low.z + (alpha2 * (high.z - low.z))) * 1.0f * (layers[m].scale);
                            }

                            alpha  = Mathf.Clamp01(layers[m].distCrv.Evaluate(r4));
                            alpha1 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r5));
                            alpha2 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r6));
                            Vector3 rot = Vector3.zero;

                            rot.x = (layers[m].rotLow.x + (alpha * (layers[m].rotHigh.x - layers[m].rotLow.x)));
                            rot.y = (layers[m].rotLow.y + (alpha * (layers[m].rotHigh.y - layers[m].rotLow.y)));
                            rot.z = (layers[m].rotLow.z + (alpha * (layers[m].rotHigh.z - layers[m].rotLow.z)));
                            rot   = Snap(rot, layers[m].snapRot);

                            float distalpha = 0.0f;

                            float maxscale = Mathf.Abs(scl.x);
                            if (Mathf.Abs(scl.z) > maxscale)
                            {
                                maxscale = Mathf.Abs(scl.z);
                            }

                            float rad = layers[m].radius * maxscale;

                            float texscale = 0.0f;

                            if (layers[m].colorTexture != null)
                            {
                                rc = -1.0f;
                            }

                            if (FindPos(m, s, ref p, scl, ref val, rad, ref texscale))
                            {
                                bool addedmesh = false;

                                alpha  = Mathf.Clamp01(layers[m].distCrv.Evaluate(r7));
                                alpha1 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r8));
                                alpha2 = Mathf.Clamp01(layers[m].distCrv.Evaluate(r9));

                                p.x += (layers[m].offsetLow.x + (alpha * (layers[m].offsetHigh.x - layers[m].offsetLow.x)));
                                p.y += (layers[m].offsetLow.y + (alpha1 * (layers[m].offsetHigh.y - layers[m].offsetLow.y)));
                                p.z += (layers[m].offsetLow.z + (alpha2 * (layers[m].offsetHigh.z - layers[m].offsetLow.z)));

                                Vector3 wp = transform.localToWorldMatrix.MultiplyPoint3x4(p);
                                Vector3 lp = transform.worldToLocalMatrix.MultiplyPoint3x4(wp);

                                float texscaleval = Mathf.Lerp(mintexscale, maxtexscale, texscale);

                                if (texscaleval > minsizetoadd)
                                {
                                    scl *= layers[m].scaleOnDist.Evaluate(distalpha) * texscaleval;
                                    rad *= texscaleval;

                                    if (raycast)
                                    {
                                        //wp.y += 100.0f;
                                        if (MultiRayCast(wp, rad * layers[m].colradiusadj, layers[m].raycount))
                                        {
                                            RaycastHit hit;
                                            Vector3    o = wp;
                                            o.y += collisionOffset;

                                            if (Physics.Raycast(o, Vector3.down, out hit, raycastheight))
                                            {
                                                float ang = Mathf.Acos(Vector3.Dot(hit.normal, Vector3.up)) * Mathf.Rad2Deg;

                                                p = hit.point;
                                                if (!layers[m].useheight || (p.y <layers[m].maxheight && p.y> layers[m].minheight))
                                                {
                                                    if (ang >= layers[m].minslope && ang <= layers[m].maxslope)
                                                    {
                                                        //p.y += layers[m].collisionOffset * scl.y;
                                                        p = transform.worldToLocalMatrix.MultiplyPoint3x4(p);

                                                        Vector3 hn = transform.worldToLocalMatrix.MultiplyVector(hit.normal);

                                                        Vector3 newup = Vector3.Lerp(Vector3.up, hn, layers[m].align).normalized;
                                                        p += newup * (layers[m].collisionOffset * scl.y);
                                                        Quaternion align = Quaternion.FromToRotation(Vector3.up, newup);

                                                        layers[m].AddSM(this, p, scl, rot, align, rc, texturecol);
                                                        addedmesh = true;
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (!NeedsGround)
                                            {
                                                layers[m].AddSM(this, lp, scl, rot, Quaternion.identity, rc, texturecol);
                                                addedmesh = true;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        layers[m].AddSM(this, lp, scl, rot, Quaternion.identity, rc, texturecol);
                                        addedmesh = true;
                                    }
                                }

                                if (!addedmesh)
                                {
                                    i--;
                                    failcount--;
                                    if (failcount < 0)
                                    {
                                        break;
                                    }
                                }
                            }
                        }

                        if (meshPerShape)
                        {
                            BuildMeshNew(layers[m]);
                        }
                    }

                    if (!meshPerShape)
                    {
                        BuildMeshNew(layers[m]);
                    }
                }
            }

            RestoreColliders();

            if (dostaticbatching)
            {
                StaticBatchingUtility.Combine(gameObject);
            }
        }
    }
Exemple #30
0
            // For computing of Frenet frames, exposing the tangents, normals and binormals the spline
            public FrenetFrames(Curve path, int segments, bool closed)
            {
                //Vector3 tangent = new Vector3 ();
                Vector3 normal = new Vector3();
                //Vector3 binormal = new Vector3 ();

                Vector3 vec = new Vector3();
                //Matrix4x4 mat = new Matrix4x4 ();

                int   numpoints = segments + 1;
                float theta;
                float epsilon = THREE.Setting.EPSILON_S;
                float smallest;

                float tx, ty, tz;
                float u;
                //float v;

                List <Vector3> tangents  = new List <Vector3> (new Vector3[numpoints]);
                List <Vector3> normals   = new List <Vector3> (new Vector3[numpoints]);
                List <Vector3> binormals = new List <Vector3> (new Vector3[numpoints]);

                //vecs = new List<Vector3>(new Vector3[numpoints]);

                // expose internals
                this.tangents  = tangents;
                this.normals   = normals;
                this.binormals = binormals;

                // compute the tangent vectors for each segment on the path
                for (int i = 0; i < numpoints; i++)
                {
                    u = (float)i / (numpoints - 1);

//					tangents [i] = path.getTangentAt(u);
//					tangents [i].Normalize ();
                    Vector3 t_vec = path.getTangentAt(u);
                    t_vec.Normalize();
                    //tangents.Add( t_vec );
                    tangents[i] = (t_vec);
                }

                //initialNormal3();

                //void initialNormal3() {
                // select an initial normal vector perpenicular to the first tangent vector,
                // and in the direction of the smallest tangent xyz component

                normals.Add(new Vector3());
                binormals.Add(new Vector3());

                smallest = Mathf.Infinity;
                tx       = Mathf.Abs(tangents [0].x);
                ty       = Mathf.Abs(tangents [0].y);
                tz       = Mathf.Abs(tangents [0].z);

                if (tx <= smallest)
                {
                    smallest = tx;
                    normal   = new Vector3(1, 0, 0);
                }

                if (ty <= smallest)
                {
                    smallest = ty;
                    normal   = new Vector3(0, 1, 0);
                }

                if (tz <= smallest)
                {
                    normal = new Vector3(0, 0, 1);
                }

                vec = Vector3.Cross(tangents [0], normal).normalized;

                //vec.crossVectors( tangents[ 0 ], normal ).normalize();

                //		normals[ 0 ].crossVectors( tangents[ 0 ], vec );
                //		binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );

                //normals.Add( Vector3.Cross (tangents [0], vec) );
                //binormals.Add(Vector3.Cross (tangents [0], normals [0]));

                normals[0]   = (Vector3.Cross(tangents [0], vec));
                binormals[0] = (Vector3.Cross(tangents [0], normals [0]));
                //}

                // compute the slowly-varying normal and binormal vectors for each segment on the path

                // js233
                for (int i = 1; i < numpoints; i++)
                {
//					normals.Add( clone (normals [i - 1]) );
//					binormals.Add( clone (binormals [i - 1]) );
                    normals[i]   = clone(normals [i - 1]);
                    binormals[i] = clone(binormals [i - 1]);

                    //vec.crossVectors( tangents[ i-1 ], tangents[ i ] );
                    vec = Vector3.Cross(tangents [i - 1], tangents [i]);

                    if (vec.magnitude > epsilon)
                    {
                        vec.Normalize();

                        //theta = Mathf.Acos( Mathf.Clamp( tangents[ i-1 ].dot( tangents[ i ] ), -1, 1 ) ); // clamp for floating pt errors
                        float dot = Vector3.Dot(tangents [i - 1], tangents [i]);
                        theta = Mathf.Acos(Mathf.Clamp(dot, -1, 1));                           // clamp for floating pt errors

                        //normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
                        Quaternion rot = Quaternion.AngleAxis(Mathf.Rad2Deg * (theta), vec);
                        normals [i] = rot * normals [i];

                        //vecs[i] = vec;
                    }
                    //binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
                    binormals [i] = Vector3.Cross(tangents [i], normals [i]);
                }


                // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same

                if (closed)
                {
                    Debug.LogWarning("close---------");
                    float dot = Vector3.Dot(normals [0], normals [numpoints - 1]);
                    theta  = Mathf.Acos(Mathf.Clamp(dot, -1, 1));
                    theta /= (float)(numpoints - 1);

                    Vector3 vec0 = Vector3.Cross(normals [0], normals [numpoints - 1]);
                    float   dot0 = Vector3.Dot(tangents [0], vec0);
                    if (dot0 > 0)
                    {
                        //if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ numpoints-1 ] ) ) > 0 ) {
                        theta = -theta;
                    }

                    for (int i = 1; i < numpoints; i++)
                    {
                        // twist a little...
                        //normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );
                        //binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );

                        Quaternion rot = Quaternion.AngleAxis(Mathf.Rad2Deg * (theta * i), tangents [i]);
                        normals [i]   = rot * normals [i];
                        binormals [i] = Vector3.Cross(tangents [i], normals [i]);
                    }
                }
            }