Dot() public method

public Dot ( Vector3 v ) : float
v Vector3
return float
Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Quaternion"/> class.
        /// </summary>
        /// <param name="sourcePosition">The source position.</param>
        /// <param name="destinationPosition">The destination position.</param>
        public Quaternion(Vector3 sourcePosition, Vector3 destinationPosition)
        {
            var r = sourcePosition.Cross(destinationPosition);
            var s = Functions.Sqrt(2 * (1 + sourcePosition.Dot(destinationPosition)));

            mValues = new Vector4(r / s, s / 2);
        }
Example #2
0
 /// 2点間の距離を返す(XとZのみ)
 public static float DistanceXZ( Vector3 pos1, Vector3 pos2 )
 {
     calPos = pos1 - pos2;
     calPos.Y = 0;
     float dis = FMath.Sqrt( calPos.Dot(calPos) );
     return dis;
 }
Example #3
0
        public MeshTriangle(byte id, Vector3 p0, Vector3 p1, Vector3 p2)
        {
            Id = id;
            P0 = p0;
            P1 = p1;
            P2 = p2;

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

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

            D = UV * UV - UU * VV;
        }
Example #4
0
        static double AngleBetweenVectors(Vector3 Vector1, Vector3 Vector2)
        {
            float dotProduct = Vector1.Dot(Vector2);
            float vectorsMagnitude = Vector1.Length * Vector2.Length;
            double angle = Math.Acos(dotProduct / vectorsMagnitude);

            if (double.IsNaN(angle))
                return 0;
            return (angle);
        }
Example #5
0
        /// <summary>
        /// 2つのベクトルがなす角をかえす
        /// </summary>
        /// <param name="vecA"></param>
        /// <param name="vecB"></param>
        /// <returns></returns>
        public static double VecToRad( Vector3 vecA, Vector3 vecB )
        {
            vecA.Normalize();
            vecB.Normalize();

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

            return dir;
        }
Example #6
0
        public double GetAngleBetweenVectors(Vector3 a, Vector3 b)
        {
            var cosAlpha = a.Dot(b) / (a.Magnitude * b.Magnitude);

            if (1 - Math.Abs(cosAlpha) < Consts.DoubleEqualityThreshold)
            {
                return cosAlpha < 0 ? Math.PI : 0;
            }

            return Math.Acos(cosAlpha);
        }
        /// <summary>
        /// Sets up the frame
        /// </summary>
        /// <param name="position"> Frame origin </param>
        /// <param name="velocity"> Velocity. Becomes frame tangent (normalised by constructor) </param>
        /// <param name="acceleration"> Acceleration. Used to calculate frame normal and binormal </param>
        public CurveFrame( Point3 position, Vector3 velocity, Vector3 acceleration )
        {
            float	sqrSpeed	= velocity.SqrLength;
            float	dotVA		= velocity.Dot( acceleration );

            Translation	= position;
            XAxis		= velocity.MakeNormal( );
            YAxis		= ( acceleration * sqrSpeed ) - ( velocity * dotVA );
            ZAxis		= Vector3.Cross( XAxis, YAxis );
            m_Speed		= Functions.Sqrt( sqrSpeed );

            //	NOTE: It's quite easy to calculate curvature here (because we've got first and second derivatives, and the square of speed, ready at hand).
            //	I've removed the calculation because it does involve a length and a cross-product, which is a bit much if the caller isn't interested in the
            //	curvature value (as is likely). Call Curve.EvaluateCurvature() instead.
        }
Example #8
0
 public void Integrate(float duration)
 {
     if (!IsAwake) return;
     LastFrameAcceleration = Acceleration;
     LastFrameAcceleration += (ForceAccumulation * InverseMass);
     Vector3 angularAcceleration = InverseInertiaTensorWorld.Transform(TorqueAccumulation);
     Velocity += (LastFrameAcceleration * duration);
     Rotation += (angularAcceleration * duration);
     Velocity *= MathHelper.Pow(LinearDrag, duration);
     Rotation *= MathHelper.Pow(AngularDrag, duration);
     Position += (Velocity * duration);
     Orientation.AddScaledVector(Rotation, duration);
     CalculateDerivedData();
     ClearAccumulation();
     if (CanSleep)
     {
         float currentMotion = Velocity.Dot(Velocity) + Rotation.Dot(Rotation);
         float bias = MathHelper.Pow(0.5f, duration);
         Motion = bias * Motion + (1.0f - bias) * currentMotion;
         if (Motion < MathHelper.SleepEpilson) IsAwake = (false);
         else if (Motion > 10 * MathHelper.SleepEpilson) Motion = 10.0f * MathHelper.SleepEpilson;
     }
 }
        /// <summary>
        ///     Gets the shortest arc quaternion to rotate this vector
        ///     to the destination vector.
        /// </summary>   
        /// <remarks>
        ///     If you call this with a dest vector that is close to the inverse
        ///     of this vector, we will rotate 180 degrees around the 'fallbackAxis'
        ///     (if specified, or a generated axis if not) since in this case
        ///     ANY axis of rotation is valid.
        /// </remarks>
        public Quaternion GetRotationTo(Vector3 destination, Vector3 fallbackAxis)
        {
            // Based on Stan Melax's article in Game Programming Gems
            Quaternion q = new Quaternion();

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

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

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

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

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

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

                q.x = c.x * inverse;
                q.y = c.y * inverse;
                q.z = c.z * inverse;
                q.w = s * 0.5f;
                q.Normalize();
            }
            return q;
        }
        public void ReadSkewMatrix( ref Matrix4 matrix, XmlNode node )
        {
            string[] values = node.InnerText.Split( (char[]) null, StringSplitOptions.RemoveEmptyEntries );
            Debug.Assert( values.Length == 7 );
            float angle = float.Parse( values[ 0 ] );
            if( angle == 0 )
                return;
            angle = MathUtil.RadiansToDegrees( angle );

            Vector3 axis = new Vector3();
            axis.x = float.Parse( values[ 0 ] );
            axis.y = float.Parse( values[ 1 ] );
            axis.z = float.Parse( values[ 2 ] );

            Vector3 along = new Vector3();
            along.x = float.Parse( values[ 3 ] );
            along.y = float.Parse( values[ 4 ] );
            along.z = float.Parse( values[ 5 ] );

            Matrix4 shear = Matrix4.Identity;
            shear[ 0, 1 ] = (float) Math.Tan( angle );
            Debug.Assert( axis.Dot( along ) < 0.001f,
                         "Vectors for skew must be perpendicular" );

            // FIXME: Handle these skews
            DebugMessage( node );
        }
        public float[] GetAutoSplatSampleNormalized( long heightMM, Vector3 normal )
        {
            AutoSplatHeightAngleRange lowerRange = null;
            AutoSplatHeightAngleRange higherRange = null;

            // We assume the ranges are sorted in increasing order by height
            foreach( AutoSplatHeightAngleRange range in m_RangeList )
            {
                if( range.HeightMM == heightMM )
                {
                    lowerRange = range;
                    higherRange = range;
                    break;
                }

                if( range.HeightMM < heightMM )
                {
                    lowerRange = range;
                    continue;
                }

                if( range.HeightMM > heightMM )
                {
                    higherRange = range;
                    // We should have both the lower & upper bounds now, so break;
                    break;
                }
            }

            if( lowerRange == null )
            {
                lowerRange = m_RangeList[ 0 ]; // allows us to continue
            }
            if( higherRange == null )
            {
                higherRange = m_RangeList[ m_RangeList.Count - 1 ]; // allows us to continue
            }

            // We want the angle of the normal relative to the XZ plane, so
            // we first use the dot product to get the angle to the Y-axis
            // which is perpendicular to the XZ plane, convert it to degress,
            // and then subtract it from 90.
            float angleRadians = normal.Dot( Vector3.UnitY );
            float angleDegrees = Convert.ToSingle( 90 - RadiansToDegrees( angleRadians ) );

            if( lowerRange == higherRange )
            {
                // No need to do any weighting since we at the exact height
                return lowerRange.GetAutoSplatSampleNormalized( angleDegrees );
            }

            // Compute the gradiant weighting for the lower & higher angled textures
            float lowerWeight;
            float higherWeight;

            long heightDiff = higherRange.HeightMM - lowerRange.HeightMM;

            if( heightDiff == 0 )
            {
                // Give equal weighting to both samples.
                // This covers the case when we have two ranges at the
                // same height....this really shouldn't happen due to the
                // way we choose the lower/higher ranges.
                lowerWeight = 0.5f;
                higherWeight = 0.5f;
            }
            else
            {
                // How close is the angle to the higher/lower angle?  Normalize
                // that distance from 0..1 and use that as the gradient weights
                higherWeight = ((float) (heightMM - lowerRange.HeightMM)) / heightDiff;
                lowerWeight = 1f - higherWeight;
            }

            float[] lowerNormalizedSample = lowerRange.GetAutoSplatSampleNormalized( angleDegrees );
            float[] higherNormalizedSample = higherRange.GetAutoSplatSampleNormalized( angleDegrees );

            float[] normalizedSample = new float[ AlphaSplatTerrainConfig.MAX_LAYER_TEXTURES ];
            for( int i = 0; i < AlphaSplatTerrainConfig.MAX_LAYER_TEXTURES; i++ )
            {
                normalizedSample[ i ] = lowerNormalizedSample[ i ] * lowerWeight +
                                      higherNormalizedSample[ i ] * higherWeight;
            }
            return normalizedSample;
        }
Example #12
0
        /// <summary>
        /// Concatenates two quaternions. The right argument is applied first.
        /// </summary>
        /// <param name="left">The left operand which is applied after the right one.</param>
        /// <param name="right">The right operand which is applied first.</param>
        /// <returns>A quaternion containing the rotations of both given quaternions.</returns>
        public static Quaternion operator *(Quaternion left, Quaternion right)
        {
            var v1 = new Vector3(right.X, right.Y, right.Z);
            var v2 = new Vector3(left.X, left.Y, left.Z);

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

            return new Quaternion(v, w);
        }
 public static float ProjectVectorOnNormalizedVector(Vector3 projectedV, Vector3 projectOnV)
 {
     return(Vector3.Dot(projectedV, projectOnV));
 }
        ////////////////////////////// CLOSET POINT ON LINE """""""""""\*
        /////
        /////	Возвращает точку на линии vA_vB, которая ближе всего к точке vPoint
        /////
        ////////////////////////////// CLOSET POINT ON LINE """""""""""\*
        static Vector3 ClosestPointOnLine(Vector3 vA, Vector3 vB, Vector3 vPoint)
        {
            // Эта функция принимает сегмент линии, от vA до vB, затем точку в пространстве,
            // vPoint. Мы хотим найти ближайшую точку отрезка vA_vB к точке в пространстве.
            // Или это будет одна из двух крайних точек линии, или точка где-то между
            // vA и vB. В отношении определения пересечений это очень важная функция.

            // Вот как это работает. Сначала это всё кажется немного запутанным, так что постарайтесь
            // сосредоточится. Сначала нам нужно найти вектор от "vA" к точке в пространстве.
            // Затем нужно нормализовать вектор от "vA" к "vB", так как нам не нужна его полная длинна,
            // только направление. Запомните это, так как позже мы будем использовать скалярное
            // произведение (dot product) при рассчетах. Итак, сейчас у нас есть 2 вектора, образующие
            // угол воображаемого треугольника на плоскости (2 точки линии и точка пространства).

            // Далее нам нужно найти величину (magnitude) сегмента линии. Это делается простой
            // формулой дистанции. Затем вычисляем dot между "vVector2" и "vVector1". Используя
            // это скалярное произведение, мы можем по существу спроэцировать vVector1 на нормализованный
            // вектор сегмента линии, "vVector2". Если результат скалярного произведения равен нулю,
            // это значит, что векторы были перпендикулярны и имели между собой угол в 90 градусов.
            // 0 - это дистанция нового спроэцированного вектора от vVector2. Если результат -
            // отрицательный, значит угол между двумя векторами более 90 градусов, что в свою очередь
            // означает, что ближайшая точка - "vA", так как этот спроэцированный вектор находится
            // снаружи линии. Если же результат - положительное число, спроэцированный вектор будет
            // находится с правой стороны "vA", но возможно и справа от "vB". Чтобы это проверить,
            // мы убедимся, что результат скалярного произведения НЕ больше дистанции "d". Если
            // он больше, то ближайшая точка - "vB".

            // Итак, мы можем найти ближайшую точку довольно просто, если это одна из крайних точек линии.
            // Но как мы найдём точку между двумя краями линии? Это просто. Посколько у нас есть
            // дистанция "t" от точки "vA" (полученная из скалярного произведения двух векторов),
            // мы просто используем наш вектор направления сегмента линии, "vVector2", и умножим его
            // на дистанцию "t". Это создаст вектор, идущий в направлении сегмента линии, с величиной
            // (magnitude) спроецированного вектора, "vVector1", от точки "vA". Затем прибавляем
            // этот вектор к "vA", что даст нам точку на линии, которая ближе всего к нашей точке
            // пространства, "vPoint".

            // Наверно, это всё очень сложно представить на основе комментариев, пока у вас
            // нет хорошего понимания линейной алгебры.


            // Создаём вектор от точки vA к точке пространства vPoint.
            Vector3 vVector1 = vPoint - vA;

            // Создаём нормализированный вектор направления от точки vA до vB.
            Vector3 vVector2 = Vector3.Normalize(vB - vA);

            // Используем формулу дистанции, чтобы найти величину (magnitude) сегмента линии.
            float d = Distance(vA, vB);

            // Используя скалярное произведение, проэцируем vVector1 на vVector2.
            // Это, по существу, даст нам расстояние от нашего спроецированного вектора до vA.
            float t = Vector3.Dot(vVector2, vVector1);

            // Если наша спроецированная дистанция от vA, "t", меньше или равна нулю, ближайшая
            // точка к vPoint - vA. Возвращаем эту точку.
            if (t <= 0)
            {
                return(vA);
            }

            // Если спроецированная дистанция от vA, "t", Больше или равна длинне сегмента линии,
            // ближайшая точка на линии - vB. Вернём её.
            if (t >= d)
            {
                return(vB);
            }

            // Здесь мы создаём вектор с длинной t и направлением vVector2.
            Vector3 vVector3 = new Vector3(vVector2.X * t, vVector2.Y * t, vVector2.Z * t);

            // Чтобы найти ближайшую точку на отрезке линии, просто прибавляем vVector3 к точке vA.
            Vector3 vClosestPoint = vA + vVector3;

            // Вернём ближайшую точку на линии
            return(vClosestPoint);
        }
Example #15
0
 public static void InersectNormal(ref Vector3 vector, ref Vector3 normal, out Vector3 result)
 {
     result = (normal * vector.Dot(normal));
 }
Example #16
0
    public override void Raycast(PointerEventData eventData, List <RaycastResult> resultAppendList)
    {
        if (canvas == null)
        {
            Debug.LogError("PvrGraphicRaycaster requires that the game object  needs 'Canvas' componet !");
            return /*false*/;
        }

        if (eventCamera == null)
        {
            Debug.LogError("PvrGraphicRaycaster requires that the eventCamera is not null");
            return;
        }

        if (canvas.renderMode != RenderMode.WorldSpace)
        {
            Debug.LogError("PvrGraphicRaycaster requires that the canvas renderMode is set to WorldSpace.");
            return /*false*/;
        }


        Ray ray = PvrInputMoudle.ray;

        if (!PUI_UnityAPI.isControllerConnected())
        {
            ray = new Ray(eventCamera.transform.position, eventCamera.transform.forward);
            PvrInputMoudle.ray = ray;
        }
        PvrInputMoudle.FindInputModule().Impl.RayDirection = ray.direction;

        float dist = 20f;

        MaxPointerEndPoint = ray.GetPoint(dist);

        Debug.DrawLine(ray.origin, ray.origin + (ray.direction * 5F), Color.red);
        float hitDistance = float.MaxValue;

        if (blockingObjects != BlockingObjects.None)   /**标记为 None 标签的不需要处理*/
        {
            if (blockingObjects == BlockingObjects.ThreeD || blockingObjects == BlockingObjects.All)
            {
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, dist, m_BlockingMask))
                {
                    hitDistance = hit.distance;
                    //Debug.Log("Hit postition : " + hit.point);
                    //Debug.Log("ditance : " + Vector3.Distance(hit.point, ray.origin) + "    Hitdistance : " + hitDistance);
                }
            }

            if (blockingObjects == BlockingObjects.TwoD || blockingObjects == BlockingObjects.All)
            {
                RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, dist, m_BlockingMask);
                if (hit.collider != null)
                {
                    hitDistance = hit.fraction * dist;
                }
            }
        }

        m_RaycastResults.Clear();
        Raycast(canvas, ray, eventCamera, dist, m_RaycastResults);

        //Debug.Log("RaycastResult 数量 : " + m_RaycastResults.Count);

        for (var index = 0; index < m_RaycastResults.Count; index++)
        {
            //Debug.Log("RaycastResult 数量 : " + m_RaycastResults.Count + " name "+m_RaycastResults[index].gameObject.name);
            var  go            = m_RaycastResults[index].gameObject;
            bool appendGraphic = true;
            if (ignoreReversedGraphics)
            {
                // If we have a camera compare the direction against the cameras forward.
                Vector3 cameraFoward = eventCamera.transform.rotation * Vector3.forward;
                Vector3 dir          = go.transform.rotation * Vector3.forward;
                appendGraphic = Vector3.Dot(cameraFoward, dir) > 0;
            }

            if (appendGraphic)
            {
                float resultDistance = 0;

                Transform trans        = go.transform;
                Vector3   transForward = trans.forward;
                // http://geomalgorithms.com/a06-_intersect-2.html
                float transDot = Vector3.Dot(transForward, trans.position - ray.origin);
                float rayDot   = Vector3.Dot(transForward, ray.direction);
                resultDistance = transDot / rayDot;
                Vector3 hitPosition = ray.origin + (ray.direction * resultDistance);
                resultDistance = resultDistance + 0;

                //Debug.Log("resultDistance : "+ resultDistance+ "      hitDistance : "+ hitDistance + "   dist "+dist);

                // Check to see if the go is behind the camera.
                if (resultDistance < 0 || resultDistance >= hitDistance || resultDistance > dist)
                {
                    continue;
                }

                //Transform pointerTransform =
                //  GvrPointerInputModule.Pointer.PointerTransform;
                //float delta = (hitPosition - pointerTransform.position).magnitude;
                //if (delta < pointerRay.distanceFromStart)
                //{
                //    continue;
                //}

                RaycastResult castResult = new RaycastResult
                {
                    gameObject     = go,
                    module         = this,
                    distance       = resultDistance,
                    worldPosition  = hitPosition,
                    screenPosition = eventCamera.WorldToScreenPoint(hitPosition),
                    index          = resultAppendList.Count,
                    depth          = m_RaycastResults[index].depth,
                    sortingLayer   = canvas.sortingLayerID,
                    sortingOrder   = canvas.sortingOrder
                };
                resultAppendList.Add(castResult);
            }
        }
        //Debug.Log("resultAppendList.Count   :  " + resultAppendList.Count);
    }
Example #17
0
        private Node GenerateTree(List <Polygon> polygons)
        {
            if (polygons.Count == 0)
            {
                return(null);
            }
            else
            {
                var polyRoot = new Node(polygons[0].ID);

                var frontPolygons = new List <Polygon>();
                var backPolygons  = new List <Polygon>();
                var d             = -Vector3.Dot(polygons[0].normal, Transformations.V4ToV3(polygons[0].vertices[0]));
                var plane         = new Vector4(polygons[0].normal, d);
                for (int i = 1; i < polygons.Count; i++)
                {
                    var polyPos = CheckPosition(polygons[i], plane);
                    if (polyPos == Position.InFront)
                    {
                        frontPolygons.Add(polygons[i]);
                    }
                    else if (polyPos == Position.Behind)
                    {
                        backPolygons.Add(polygons[i]);
                    }
                    else
                    {
                        var d2 = -Vector3.Dot(polygons[i].normal, Transformations.V4ToV3(polygons[i].vertices[0]));

                        var v   = Vector3.Cross(polygons[0].normal, polygons[i].normal);
                        var dot = Vector3.Dot(v, v);

                        var u1 = d2 * polygons[0].normal;
                        var u2 = -d * polygons[i].normal;
                        var p  = Vector3.Cross(u1 + u2, v / dot);

                        int     p1pos = -1, p2pos = -1;
                        Vector3 point1 = new Vector3(), point2 = new Vector3();
                        for (int j = 0; j < polygons[i].vertices.Length; j++)
                        {
                            var current = polygons[i].vertices[j];
                            var next    = polygons[i].vertices[(j + 1) % polygons[i].vertices.Length];

                            if (Vector4.Dot(current, plane) * Vector4.Dot(next, plane) <= 0)
                            {
                                var u = Transformations.V4ToV3(next - current);
                                var a = Vector3.Cross(v, u);
                                var b = Vector3.Cross(Transformations.V4ToV3(next) - p, u);

                                var t = 0.0F;
                                if (a.X != 0)
                                {
                                    t = b.X / a.X;
                                }
                                else if (a.Y != 0)
                                {
                                    t = b.Y / a.Y;
                                }
                                else if (a.Z != 0)
                                {
                                    t = b.Z / a.Z;
                                }

                                if (p1pos == -1)
                                {
                                    point1 = p + (t * v);
                                    p1pos  = j + 1;
                                }
                                else
                                {
                                    point2 = p + (t * v);
                                    p2pos  = j + 1;
                                }
                            }
                        }

                        var poly1 = new Polygon {
                            ID = Polygons.Count, vertices = new Vector4[p1pos + (polygons[i].vertices.Length - p2pos) + 2], normal = polygons[i].normal
                        };
                        for (int j = 0, k = 0; k < p1pos; j++, k++)
                        {
                            poly1.vertices[j] = polygons[i].vertices[k];
                        }
                        poly1.vertices[p1pos]     = new Vector4(point1, 1.0F);
                        poly1.vertices[p1pos + 1] = new Vector4(point2, 1.0F);
                        for (int j = p1pos + 2, k = p2pos; k < polygons[i].vertices.Length; j++, k++)
                        {
                            poly1.vertices[j] = polygons[i].vertices[k];
                        }
                        poly1.normal = Transformations.CalculateSurfaceNormal(poly1);
                        Polygons.Add(poly1);

                        var poly2 = new Polygon {
                            ID = Polygons.Count, vertices = new Vector4[p2pos - p1pos + 2], normal = polygons[i].normal
                        };
                        poly2.vertices[0] = new Vector4(point1, 1.0F);
                        for (int j = 1, k = p1pos; k < p2pos; j++, k++)
                        {
                            poly2.vertices[j] = polygons[i].vertices[k];
                        }
                        poly2.vertices[p2pos - p1pos + 1] = new Vector4(point2, 1.0F);
                        Polygons.Add(poly2);

                        if (CheckPosition(poly1, plane) == Position.InFront)
                        {
                            frontPolygons.Add(poly1);
                            backPolygons.Add(poly2);
                        }
                        else
                        {
                            frontPolygons.Add(poly2);
                            backPolygons.Add(poly1);
                        }
                    }
                }

                polyRoot.Front = GenerateTree(frontPolygons);
                polyRoot.Back  = GenerateTree(backPolygons);
                return(polyRoot);
            }
        }
Example #18
0
        /// <summary>
        /// Tessellate a solid cone by specifying the facet chord length around the base circle.
        /// </summary>
        /// <param name="vertices">Populated with the cone vertices (output).</param>
        /// <param name="normals">Populated with the cone normals (output).</param>
        /// <param name="indices">Populated with the triangle indices (output).</param>
        /// <param name="apex">The cone apex vertex to construct with.</param>
        /// <param name="axis">The cone primary axis (direction) to construct with.</param>
        /// <param name="length">The cone length.</param>
        /// <param name="angle">The cone angle between the wall and the primary <paramref name="axis"/>
        ///     (radians).</param>
        /// <param name="baseChordLength">The chord length around the base circle.</param>
        /// <param name="tessellateBase">Tessellate the base (true) or leave it open (false).</param>
        /// <returns>True on success, false if the arguments prevent tessellation.</returns>
        /// <remarks>
        /// This method tessellates to try and keep quadrilaterals (trapezoids) of the same area.
        /// The cone is divided into rings, but the distance between the rings increases
        /// away from the cone base in order to maintain a similar area.
        /// The last division is set to consume the remainder. The ASCII art below illustrates the
        /// divisions.
        ///
        /// <code>
        /// Cone setup:
        /// h[3] = 0    /\
        ///            /  \
        ///           /    \
        ///          /      \
        /// h[2]    /--------\
        ///        /          \
        /// h[1]  /------------\
        /// h[0] /--------------\
        ///
        /// h[n] defines the length of each ring from the apex, with:
        ///  h[0] &lt; h[1] &lt; ... &lt; h[n-1] &lt; h[n]
        /// </code>
        ///
        /// There are a known number of facets around the ring, where <c>c[n]</c> is
        /// the chord length of a facet (defined by the ring of radius <c>r[n]</c>).
        /// Set <c>c[0] = baseChordLength</c>, which generally defines the tessellation resolution.
        /// </remarks>
        public static bool SolidByBaseChord(List <Vector3> vertices, List <Vector3> normals, List <int> indices,
                                            Vector3 apex, Vector3 axis, float length, float angle,
                                            float baseChordLength = 0, bool tessellateBase = true)
        {
            float quadArea     = baseChordLength * baseChordLength;
            float baseRadius   = length * Mathf.Tan(angle);
            float segmentAngle = 2.0f * Mathf.Asin(baseChordLength / (2 * baseRadius));
            int   facets       = Mathf.FloorToInt(2.0f * Mathf.PI / segmentAngle + 0.5f);
            float facetAngle   = 2.0f * Mathf.PI / facets;

            if (facets < MinFacets)
            {
                facets          = MinFacets;
                facetAngle      = 2.0f * Mathf.PI / facets;
                baseChordLength = 2 * baseRadius * Mathf.Sin(0.5f * facetAngle);
                quadArea        = baseChordLength * baseChordLength;
            }
            segmentAngle = 2.0f * Mathf.PI / facets;

            if (baseChordLength <= 0)
            {
                return(false);
            }

            // Building on the XML comment above:
            // Constants or initial values:
            // A: quadArea (c[0] * c[0])
            // theta: cone angle
            // phi: segmentAngle

            // At ring n:
            // r[n] : ring radius
            // c[n] : facet chord length (trapezoid base length).
            // d[n] : distance to the next ring (n+1).
            // h[n] : ring length or the distance from the cone apex to the ring.
            // A : quadArea
            //
            // A[i] = A[j] = quadArea                 Constant
            // A[n] = d[n] * (c[n-1] + c[n]) / 2      Trapezoid area.

            // c[n] = 2r[n] sin(phi / 2)              (1)
            // d[n] = 2A / (c[n-1] + c[n])            (2)
            // h[n-1] = h[n] + d[n]                   (3)
            // h[n] = r[n] / tan(theta)               (4)

            // Thus from (4):
            // r[n] = h[n] tan(theta)                 (4a)
            // Substitute (3) in (4a):
            // r[n] = (h[n-1] - d[n]) tan(theta)      (5)
            //
            // Substitute (5) in (1):
            // c[n] = 2(h[n-1] - d[n]) tan(theta) sin(phi/2)
            // Let T = 2 * tan(theta) sin(phi/2)
            // c[n] = T(h[n-1] - d[n])                (6)
            //
            // Substitute (2) in (6):
            // c[n] = T(h[n-1] - 2A / (c[n-1] + c[n]))
            // ...
            // c[n] * c[n] + (c[n-1] - Th[n-1])c[n] + T(2A - h[n-1]c[n-1]) = 0
            //                                        (7)
            //
            // However, we can show that the coefficient of c[n] is zero:
            // From (4):
            // r[n] = h[n] tan(theta)                 (4a)
            // Substitute (4a) in (1):
            // c[n] = 2 h[n] tan(theta) sin(phi / 2)
            //      = h[n] 2 tan(theta) sin(phi / 2)
            //      = Th[n]
            // Therefore:
            // c[n-1] = Th[n-1]                       (8)
            //
            // Substitute (8) in (7):
            // c[n] * c[n] + (c[n-1] - Th[n-1])c[n] + T(2A - h[n-1]c[n-1]) = 0
            // c[n] * c[n] + (c[n-1] - c[n-1])c[n] + T(2A - h[n-1]c[n-1])  = 0
            // c[n] * c[n] + T(2A - h[n-1]c[n-1])                          = 0
            // c[n] * c[n] = -T(2A - h[n-1]c[n-1])
            // c[n] * c[n] = T(h[n-1]c[n-1] - 2A)
            // c[n] = sqrt(T(h[n-1]c[n-1] - 2A))      (9)
            //
            // We continue so long as the root term in (9) is positive. The sign changes
            // once we pass the cone apex. We also add a restriction h[n] >= baseChordLength,
            // stopping once that fails. I suspect that this only occurs once the root term
            // in (9) changes sign.

            // We don't know how many vertices we have head of time.

            Vector3[] radials        = new Vector3[2];
            float     nearAlignedDot = Mathf.Cos(85.0f / 180.0f * Mathf.PI);

            if (Vector3.Dot(axis, new Vector3(0, 1, 0)) < nearAlignedDot)
            {
                radials[0] = Vector3.Cross(new Vector3(0, 1, 0), axis).normalized;
            }
            else
            {
                radials[0] = Vector3.Cross(new Vector3(1, 0, 0), axis).normalized;
            }
            radials[1] = Vector3.Cross(axis, radials[0]).normalized;

            // Add the base ring.
            // We build vertices for each ring first, then tessellate between the rings.
            Vector3 ringCentre, radial, vertex, firstVertex, normal;

            // Add each following ring.
            int   rings = 0;
            float hn = length;              // h[n]
            float cn = baseChordLength;     // c[n]
            float dn = 0;                   // d[n]
            float radius = baseChordLength; // r[n-1]
            float hp, cp;                   // h[n-1] and c[n-1] ('p' for previous).
                                            // let T = 2 * tan(theta) sin(phi/2)
            float T = 2 * Mathf.Tan(angle) * Mathf.Sin(0.5f * segmentAngle);

            while (hn > baseChordLength)
            {
                hp = hn;
                cp = cn;

                // Add vertices for the ring at hp before.
                {
                    //// Bitmap V coordinate:
                    //// 1 at base, zero at apex.
                    //float uf = (hn / length);
                    radius = hp * Mathf.Tan(angle);
                    //float vrange = radius / baseRadius;
                    //float vstart = 0.5f - 0.5f * vrange;
                    //float rlen;
                    ringCentre  = apex + hp * axis;
                    firstVertex = ringCentre + radius * radials[0];
                    vertices.Add(firstVertex);

                    for (int f = 1; f < facets; ++f)
                    {
                        //// Bitmap V coordinate. Range varies such that at the base it is [0, 1] and it is 0.5 a the apex.
                        //float vf = vstart + vrange * ((float)f / (float)facets);
                        float currentFacetAngle = f * segmentAngle;
                        radial = radius * (Mathf.Cos(currentFacetAngle) * radials[0] + Mathf.Sin(currentFacetAngle) * radials[1]);
                        //rlen = radial.magnitude;
                        vertex = ringCentre + radial;
                        vertices.Add(vertex);
                    }
                }

                // c[n] = sqrt(T(h[n-1]c[n-1] - 2A))      (9)
                float rootTerm = T * (hp * cp - 2 * quadArea);
                if (rootTerm > 0)
                {
                    cn = Mathf.Sqrt(rootTerm);

                    // d[n] = 2A / (c[n-1] + c[n])            (2)
                    dn = 2 * quadArea / (cp + cn);

                    // Setup next iteration.
                    hn = hp - dn;
                }
                else
                {
                    hn = dn = 0;
                }
                ++rings;
            }

            // Add the apex vertex as the last vertex.
            // Add apex vertices. If not generating normals, we just add one.
            // If generating normals, we add one for each facet to support individual normals.
            int apexStart = vertices.Count;

            if (normals == null)
            {
                vertices.Add(apex);
            }
            else
            {
                for (int i = 0; i < facets; ++i)
                {
                    vertices.Add(apex);
                }

                // Add normals for each of the existing vertices.
                // Each facet vertex has the same normal as the other vertices for the same facet.
                Vector3 toApex, v;
                // rings + 1 to cover the apex vertices
                for (int r = 0; r < rings + 1; ++r)
                {
                    for (int f = 0; f < facets; ++f)
                    {
                        normal = vertices[f]; // Always start with base vertex.
                        // Find the vector to the apex.
                        toApex = apex - normal;
                        // Remove height component from the future normal
                        normal -= Vector3.Dot(normal, axis) * axis;
                        //normal.Normalize();

                        // Cross and normalise to get the actual normal.
                        v      = Vector3.Cross(toApex, normal);
                        normal = Vector3.Cross(v, toApex).normalized;

                        normals.Add(normal);
                    }
                }
            }

            // Now triangulate between the rings.
            for (int r = 1; r < rings; ++r)
            {
                int ringStartIndex     = r * facets;
                int prevRingStartIndex = ringStartIndex - facets;
                for (int f = 0; f < facets; ++f)
                {
                    indices.Add(prevRingStartIndex + f);
                    indices.Add(ringStartIndex + (f + 1) % facets);
                    indices.Add(prevRingStartIndex + (f + 1) % facets);

                    indices.Add(prevRingStartIndex + f);
                    indices.Add(ringStartIndex + f);
                    indices.Add(ringStartIndex + (f + 1) % facets);
                }
            }

            // Triangulate with the apex vertex.
            int lastStartIndex = (rings - 1) * facets;

            if (normals == null)
            {
                for (int f = 0; f < facets; ++f)
                {
                    indices.Add(apexStart); // Apex vertex
                    indices.Add(lastStartIndex + (f + 1) % facets);
                    indices.Add(lastStartIndex + f);
                }
            }
            else
            {
                for (int f = 0; f < facets; ++f)
                {
                    indices.Add(apexStart + f); // Apex vertex
                    indices.Add(lastStartIndex + (f + 1) % facets);
                    indices.Add(lastStartIndex + f);
                }
            }

            if (tessellateBase)
            {
                // Add and tessellate base vertices. We copy or re-use the initial ring
                int firstBaseIndex = 0;
                if (normals != null)
                {
                    // Copy initial ring.
                    firstBaseIndex = vertices.Count;
                    for (int i = 0; i < facets; ++i)
                    {
                        vertices.Add(vertices[i]);
                        normals.Add(axis);
                    }
                }

                for (int i = 1; i < facets - 1; ++i)
                {
                    indices.Add(firstBaseIndex);
                    indices.Add(firstBaseIndex + i);
                    indices.Add(firstBaseIndex + i + 1);
                }
            }

            return(true);
        }
Example #19
0
		/// <summary>
		/// Calculate a rotatation based on mouse movement
		/// </summary>
		Quaternion ArcBall(Vector3 from, Vector3 to)
		{
            float dot = Vector3.Dot(from, to);
            Vector3 part = Vector3.Cross(from, to);
            return new Quaternion(part.X, part.Y, part.Z, dot);
		}
Example #20
0
        public Mesh InitializeStarfield()
        {
            float     arg_49_0  = (!(Camera.main != null)) ? ((!(Camera.current != null)) ? 990f : Camera.current.farClipPlane) : (Camera.main.farClipPlane - 10f);
            float     num       = 5200f;
            float     size      = num / 100f * this.starSizeScale;
            TextAsset textAsset = Resources.Load <TextAsset>("StarsData");

            if (textAsset == null)
            {
                Debug.Log("Can't find or read StarsData.bytes file.");
                return(null);
            }
            StarField.Star[] array = new StarField.Star[9110];
            using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(textAsset.bytes)))
            {
                for (int i = 0; i < 9110; i++)
                {
                    array[i].position.x = binaryReader.ReadSingle();
                    array[i].position.z = binaryReader.ReadSingle();
                    array[i].position.y = binaryReader.ReadSingle();
                    array[i].position   = Vector3.Scale(array[i].position, new Vector3(-1f, 1f, -1f));
                    array[i].color.r    = binaryReader.ReadSingle();
                    array[i].color.g    = binaryReader.ReadSingle();
                    array[i].color.b    = binaryReader.ReadSingle();
                    float a = Vector3.Dot(new Vector3(array[i].color.r, array[i].color.g, array[i].color.b), new Vector3(0.22f, 0.707f, 0.071f));
                    array[i].color.a = a;
                    if (array[i].position.y >= 0.1f && array[i].color.a >= 0.017037f)
                    {
                        CombineInstance item = default(CombineInstance);
                        item.mesh      = this.createQuad(size);
                        item.transform = this.BillboardMatrix(array[i].position * num);
                        Color[] colors = new Color[]
                        {
                            array[i].color,
                            array[i].color,
                            array[i].color,
                            array[i].color
                        };
                        item.mesh.colors = colors;
                        this.starQuad.Add(item);
                    }
                }
            }
            Mesh mesh = new Mesh();

            mesh.name = "StarFieldMesh";
            mesh.CombineMeshes(this.starQuad.ToArray());
            for (int j = 0; j < this.starQuad.Count; j++)
            {
                if (Application.isPlaying)
                {
                    UnityEngine.Object.Destroy(this.starQuad[j].mesh);
                }
                else
                {
                    UnityEngine.Object.DestroyImmediate(this.starQuad[j].mesh);
                }
            }
            this.starQuad.Clear();
            mesh.Optimize();
            mesh.bounds = new Bounds(Vector3.zero, Vector3.one * 2E+09f);
            return(mesh);
        }
Example #21
0
        /// <summary>
        /// Initializes translation-specific manipulator data and functions
        /// </summary>
        private void InitTranslation()
        {
            Dictionary <AxisFlags, Matrix> axis_transforms = new Dictionary <AxisFlags, Matrix>();

            axis_transforms[AxisFlags.X] = Matrix.CreateRotationZ(-MathHelper.PiOver2);
            axis_transforms[AxisFlags.Y] = Matrix.Identity;
            axis_transforms[AxisFlags.Z] = Matrix.CreateRotationX(MathHelper.PiOver2);
            axis_transforms[AxisFlags.X | AxisFlags.Y] = Matrix.Identity;
            axis_transforms[AxisFlags.X | AxisFlags.Z] = Matrix.CreateRotationX(MathHelper.PiOver2);
            axis_transforms[AxisFlags.Y | AxisFlags.Z] = Matrix.CreateRotationY(-MathHelper.PiOver2);

            // the base draw handler for single-axis draw calls
            Action <Matrix> base_draw_axis = new Action <Matrix>(delegate(Matrix transform)
            {
                GraphicsDevice device = mGraphics.GraphicsDevice;

                ManipulatorSettings.TranslationSettings settings = mSettings.Translation;

                // draw the axis cylinder to represent the axis itself
                if ((settings.AxisDrawMode & AxisDirections.Positive) == AxisDirections.Positive)
                {
                    XPrimitives.DrawCylinder(device, Vector3.UnitY * settings.AxisExtent * 0.5f,
                                             settings.AxisExtent * 0.5f, settings.AxisRadius, 8, transform);
                    XPrimitives.DrawCone(device, Vector3.UnitY * settings.AxisExtent, settings.ConeRadius,
                                         settings.ConeHeight, 8, transform);
                }

                if ((settings.AxisDrawMode & AxisDirections.Negative) == AxisDirections.Negative)
                {
                    Matrix y_invert = Matrix.CreateRotationX(MathHelper.Pi);

                    XPrimitives.DrawCylinder(device, -Vector3.UnitY * settings.AxisExtent * 0.5f,
                                             settings.AxisExtent * 0.5f, settings.AxisRadius, 8, transform);
                    XPrimitives.DrawCone(device, Vector3.UnitY * settings.AxisExtent, settings.ConeRadius,
                                         settings.ConeHeight, 8, y_invert * transform);
                }
            });

            // use the base single axis draw function for each of the main axes, and
            // transform using the appropriate axis transform from the array defined aboved
            mDrawFunctions[TransformationMode.TranslationAxis][AxisFlags.X]
                    = mDrawFunctions[TransformationMode.TranslationAxis][AxisFlags.Y]
                    = mDrawFunctions[TransformationMode.TranslationAxis][AxisFlags.Z]
                    = delegate(AxisFlags axis)
                {
                base_draw_axis(axis_transforms[axis]);
                };

            Action <Matrix> base_draw_plane = new Action <Matrix>(delegate(Matrix transform)
            {
                GraphicsDevice device = mGraphics.GraphicsDevice;
                ManipulatorSettings.TranslationSettings settings = mSettings.Translation;

                Vector3 up    = Vector3.UnitY * settings.PlaneQuadrantSize;
                Vector3 right = Vector3.UnitX * settings.PlaneQuadrantSize;

                bool draw_pos = (settings.AxisDrawMode & AxisDirections.Positive) == AxisDirections.Positive;
                bool draw_neg = (settings.AxisDrawMode & AxisDirections.Negative) == AxisDirections.Negative;

                if (draw_pos)
                {
                    XPrimitives.DrawTriangle(device, up, right, Vector3.Zero, transform);
                }

                if (draw_neg)
                {
                    XPrimitives.DrawTriangle(device, -up, -right, Vector3.Zero, transform);
                }

                if (draw_pos && draw_neg)
                {
                    XPrimitives.DrawTriangle(device, -up, right, Vector3.Zero, transform);
                    XPrimitives.DrawTriangle(device, up, -right, Vector3.Zero, transform);
                }
            });

            mDrawFunctions[TransformationMode.TranslationPlane][AxisFlags.X | AxisFlags.Y]
                    = mDrawFunctions[TransformationMode.TranslationPlane][AxisFlags.X | AxisFlags.Z]
                    = mDrawFunctions[TransformationMode.TranslationPlane][AxisFlags.Y | AxisFlags.Z]
                    = delegate(AxisFlags axis)
                {
                base_draw_plane(axis_transforms[axis]);
                };

            // all single-axis translations will use the same manip function
            mManipFunctions[TransformationMode.TranslationAxis][AxisFlags.X]
                    = mManipFunctions[TransformationMode.TranslationAxis][AxisFlags.Y]
                    = mManipFunctions[TransformationMode.TranslationAxis][AxisFlags.Z]
                    = delegate()
                {
                // get the unit version of the seclected axis
                Vector3 axis = GetUnitAxis(mSelectedAxes);

                // we need to project using the translation component of the current
                // ITransform in order to obtain a projected unit axis originating
                // from the transform's position
                Matrix translation = Matrix.CreateTranslation(mTransform.Translation);

                // project the origin onto the screen at the transform's position
                Vector3 start_position = Viewport.Project(Vector3.Zero, ProjectionMatrix, ViewMatrix, translation);
                // project the unit axis onto the screen at the transform's position
                Vector3 end_position = Viewport.Project(axis, ProjectionMatrix, ViewMatrix, translation);

                // calculate the normalized direction vector of the unit axis in screen space
                Vector3 screen_direction = Vector3.Normalize(end_position - start_position);

                // calculate the projected mouse delta along the screen direction vector
                end_position = start_position + (screen_direction * (Vector3.Dot(new Vector3(mInput.Delta, 0f), screen_direction)));

                // unproject the screen points back into world space using the translation transform
                // to get the world space start and end positions in regard to the mouse delta along
                // the mouse direction vector
                start_position = Viewport.Unproject(start_position, ProjectionMatrix, ViewMatrix, translation);
                end_position   = Viewport.Unproject(end_position, ProjectionMatrix, ViewMatrix, translation);

                // calculate the difference vector between the world space start and end points
                Vector3 difference = end_position - start_position;

                // create a view frustum based on the  current view and projection matrices
                BoundingFrustum frust = new BoundingFrustum(ViewMatrix * ProjectionMatrix);

                // if the new translation position is within the current frustum, then add the difference
                // to the current transform's translation component, otherwise the transform would be outside of
                // the screen
                if (frust.Contains(mTransform.Translation + difference) == ContainmentType.Contains)
                {
                    mTransform.Translation += difference;
                }
                };

            // all planetranslations will use the same manip function
            mManipFunctions[TransformationMode.TranslationPlane][AxisFlags.X | AxisFlags.Y]
                    = mManipFunctions[TransformationMode.TranslationPlane][AxisFlags.X | AxisFlags.Z]
                    = mManipFunctions[TransformationMode.TranslationPlane][AxisFlags.Y | AxisFlags.Z]
                    = delegate()
                {
                // get the plane representing the two selected axes
                Plane p = GetPlane(mSelectedAxes);

                // cast rays into the scene from the mouse start and end points
                Ray sray = GetPickRay(mInput.Start);
                Ray eray = GetPickRay(mInput.End);

                // intersect the pick rays with the dual axis plane we want to move along
                float?sisect = sray.Intersects(p);
                float?eisect = eray.Intersects(p);

                // if either of the intersections is invalid then bail out as it would
                // be impossible to calculate the difference
                if (!sisect.HasValue || !eisect.HasValue)
                {
                    return;
                }

                // obtain the intersection points of each ray with the dual axis plane
                Vector3 spos = sray.Position + (sray.Direction * sisect.Value);
                Vector3 epos = eray.Position + (eray.Direction * eisect.Value);

                // calculate the difference between the intersection points
                Vector3 diff = epos - spos;

                // obtain the current view frustum using the camera's view and projection matrices
                BoundingFrustum frust = new BoundingFrustum(ViewMatrix * ProjectionMatrix);

                // if the new translation is within the current camera frustum, then add the difference
                // to the current transformation's translation component
                if (frust.Contains(mTransform.Translation + diff) == ContainmentType.Contains)
                {
                    mTransform.Translation += diff;
                }
                };
        }
Example #22
0
        // Update is called once per frame
        void Update()
        {
            if (fpsOn)
            {
                return;
            }

            if (Time.timeScale == 1)
            {
                deltaT = Time.deltaTime;
            }
            else if (Time.timeScale > 1)
            {
                deltaT = Time.deltaTime / Time.timeScale;
            }
            else
            {
                deltaT = 0.015f;
            }


                        #if UNITY_IPHONE || UNITY_ANDROID || UNITY_WP8 || UNITY_BLACKBERRY
            if (enableTouchPan)
            {
                Quaternion camDir = Quaternion.Euler(0, transform.eulerAngles.y, 0);
                if (Input.touchCount == 1)
                {
                    Touch touch = Input.touches[0];
                    if (touch.phase == TouchPhase.Moved)
                    {
                        Vector3 deltaPos = touch.position;

                        if (lastTouchPos != new Vector3(9999, 9999, 9999))
                        {
                            deltaPos = deltaPos - lastTouchPos;
                            moveDir  = new Vector3(deltaPos.x, 0, deltaPos.y).normalized *-1;
                        }

                        lastTouchPos = touch.position;
                    }
                }
                else
                {
                    lastTouchPos = new Vector3(9999, 9999, 9999);
                }

                Vector3 dir = thisT.InverseTransformDirection(camDir * moveDir) * 1.5f;
                thisT.Translate(dir * panSpeed * deltaT);

                moveDir = moveDir * (1 - deltaT * 5);
            }

            if (enableTouchZoom)
            {
                if (Input.touchCount == 2)
                {
                    Touch touch1 = Input.touches[0];
                    Touch touch2 = Input.touches[1];

                    //~ Vector3 zoomScreenPos=(touch1.position+touch2.position)/2;

                    if (touch1.phase == TouchPhase.Moved && touch1.phase == TouchPhase.Moved)
                    {
                        Vector3 dirDelta = (touch1.position - touch1.deltaPosition) - (touch2.position - touch2.deltaPosition);
                        Vector3 dir      = touch1.position - touch2.position;
                        float   dot      = Vector3.Dot(dirDelta.normalized, dir.normalized);

                        if (Mathf.Abs(dot) > 0.7f)
                        {
                            touchZoomSpeed = dir.magnitude - dirDelta.magnitude;
                        }
                    }
                }

                if (touchZoomSpeed < 0)
                {
                    if (Vector3.Distance(camT.position, thisT.position) < maxZoomDistance)
                    {
                        camT.Translate(Vector3.forward * Time.deltaTime * zoomSpeed * touchZoomSpeed);
                        currentZoom += Time.deltaTime * zoomSpeed * touchZoomSpeed;
                    }
                }
                else if (touchZoomSpeed > 0)
                {
                    if (Vector3.Distance(camT.position, thisT.position) > minZoomDistance)
                    {
                        camT.Translate(Vector3.forward * Time.deltaTime * zoomSpeed * touchZoomSpeed);
                        currentZoom += Time.deltaTime * zoomSpeed * touchZoomSpeed;
                    }
                }

                touchZoomSpeed = touchZoomSpeed * (1 - Time.deltaTime * 5);
            }

            if (enableTouchRotate)
            {
                if (Input.touchCount == 2)
                {
                    Touch touch1 = Input.touches[0];
                    Touch touch2 = Input.touches[1];

                    Vector2 delta1 = touch1.deltaPosition.normalized;
                    Vector2 delta2 = touch2.deltaPosition.normalized;
                    Vector2 delta  = (delta1 + delta2) / 2;

                    float rotX = thisT.rotation.eulerAngles.x - delta.y * rotationSpeed;
                    float rotY = thisT.rotation.eulerAngles.y + delta.x * rotationSpeed;
                    rotX = Mathf.Clamp(rotX, minRotateAngle, maxRotateAngle);

                    //~ Quaternion rot=Quaternion.Euler(delta.y, delta.x, 0);
                    //Debug.Log(rotX+"   "+rotY);
                    thisT.rotation = Quaternion.Euler(rotX, rotY, 0);
                    //thisT.rotation*=rot;
                }
            }
                        #endif



                        #if UNITY_EDITOR || !(UNITY_IPHONE && UNITY_ANDROID && UNITY_WP8 && UNITY_BLACKBERRY)
            //mouse and keyboard
            if (enableMouseRotate)
            {
                if (Input.GetMouseButtonDown(1))
                {
                    initialMousePosX = Input.mousePosition.x;
                    initialMousePosY = Input.mousePosition.y;
                    initialRotX      = thisT.eulerAngles.y;
                    initialRotY      = thisT.eulerAngles.x;
                }

                if (Input.GetMouseButton(1))
                {
                    float deltaX    = Input.mousePosition.x - initialMousePosX;
                    float deltaRotX = (.1f * (initialRotX / Screen.width));
                    float rotX      = deltaX + deltaRotX;

                    float deltaY    = initialMousePosY - Input.mousePosition.y;
                    float deltaRotY = -(.1f * (initialRotY / Screen.height));
                    float rotY      = deltaY + deltaRotY;
                    float y         = rotY + initialRotY;

                    //limit the rotation
                    if (y > maxRotateAngle)
                    {
                        initialRotY -= (rotY + initialRotY) - maxRotateAngle;
                        y            = maxRotateAngle;
                    }
                    else if (y < minRotateAngle)
                    {
                        initialRotY += minRotateAngle - (rotY + initialRotY);
                        y            = minRotateAngle;
                    }

                    thisT.rotation = Quaternion.Euler(y, rotX + initialRotX, 0);
                }
            }

            Quaternion direction = Quaternion.Euler(0, thisT.eulerAngles.y, 0);


            if (enableKeyPanning)
            {
                if (Input.GetButton("Horizontal"))
                {
                    Vector3 dir = transform.InverseTransformDirection(direction * Vector3.right);
                    thisT.Translate(dir * panSpeed * deltaT * Input.GetAxisRaw("Horizontal"));
                }

                if (Input.GetButton("Vertical"))
                {
                    Vector3 dir = transform.InverseTransformDirection(direction * Vector3.forward);
                    thisT.Translate(dir * panSpeed * deltaT * Input.GetAxisRaw("Vertical"));
                }
            }
            if (enableMousePanning)
            {
                Vector3 mousePos = Input.mousePosition;
                Vector3 dirHor   = transform.InverseTransformDirection(direction * Vector3.right);
                if (mousePos.x <= 0)
                {
                    thisT.Translate(dirHor * panSpeed * deltaT * -3);
                }
                else if (mousePos.x <= mousePanningZoneWidth)
                {
                    thisT.Translate(dirHor * panSpeed * deltaT * -1);
                }
                else if (mousePos.x >= Screen.width)
                {
                    thisT.Translate(dirHor * panSpeed * deltaT * 3);
                }
                else if (mousePos.x > Screen.width - mousePanningZoneWidth)
                {
                    thisT.Translate(dirHor * panSpeed * deltaT * 1);
                }

                Vector3 dirVer = transform.InverseTransformDirection(direction * Vector3.forward);
                if (mousePos.y <= 0)
                {
                    thisT.Translate(dirVer * panSpeed * deltaT * -3);
                }
                else if (mousePos.y <= mousePanningZoneWidth)
                {
                    thisT.Translate(dirVer * panSpeed * deltaT * -1);
                }
                else if (mousePos.y >= Screen.height)
                {
                    thisT.Translate(dirVer * panSpeed * deltaT * 3);
                }
                else if (mousePos.y > Screen.height - mousePanningZoneWidth)
                {
                    thisT.Translate(dirVer * panSpeed * deltaT * 1);
                }
            }


            if (enableMouseZoom)
            {
                float zoomInput = Input.GetAxis("Mouse ScrollWheel");
                if (zoomInput != 0)
                {
                    currentZoom += zoomSpeed * zoomInput;
                    currentZoom  = Mathf.Clamp(currentZoom, -maxZoomDistance, -minZoomDistance);
                }
            }
                        #endif


            if (avoidClipping)
            {
                Vector3    aPos = thisT.TransformPoint(new Vector3(0, 0, currentZoom));
                Vector3    dirC = aPos - thisT.position;
                float      dist = Vector3.Distance(aPos, thisT.position);
                RaycastHit hit;
                obstacle = Physics.Raycast(thisT.position, dirC, out hit, dist);

                if (!obstacle)
                {
                    float camZ = Mathf.Lerp(camT.localPosition.z, currentZoom, Time.deltaTime * 4);
                    camT.localPosition = new Vector3(camT.localPosition.x, camT.localPosition.y, camZ);
                }
                else
                {
                    dist = Vector3.Distance(hit.point, thisT.position) * 0.85f;
                    float camZ = Mathf.Lerp(camT.localPosition.z, -dist, Time.deltaTime * 50);
                    camT.localPosition = new Vector3(camT.localPosition.x, camT.localPosition.y, camZ);
                }
            }
            else
            {
                float camZ = Mathf.Lerp(camT.localPosition.z, currentZoom, Time.deltaTime * 4);
                camT.localPosition = new Vector3(camT.localPosition.x, camT.localPosition.y, camZ);
            }


            float x = Mathf.Clamp(thisT.position.x, minPosX, maxPosX);
            float z = Mathf.Clamp(thisT.position.z, minPosZ, maxPosZ);

            thisT.position = new Vector3(x, thisT.position.y, z);
        }
Example #23
0
 /// <summary>
 /// Compares if a and b are nearly on the same axis and will probably return a zero vector from a cross product
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <param name="epsilon"></param>
 /// <returns></returns>
 public static bool NearSameAxis(Vector3 a, Vector3 b, float epsilon = MathUtil.EPSILON)
 {
     return MathUtil.FuzzyEqual(Mathf.Abs(Vector3.Dot(a.normalized, b.normalized)), 1.0f, epsilon);
 }
Example #24
0
        /// <summary>
        /// The Unity Update() method.
        /// </summary>
        public void Update()
        {
            // To use Recording API:
            // 1. Create an instance of ARCoreRecordingConfig. The Mp4DatasetFilepath needs to
            // be accessible by the app, e.g. Application.persistentDataPath, or you can request
            // the permission of external storage.
            // 2. Call Session.StartRecording(ARCoreRecordingConfig) when a valid ARCore session
            // is available.
            // 3. Call Session.StopRecording() to end the recording. When
            // ARCoreRecordingConfig.AutoStopOnPause is true, it can also stop recording when
            // the ARCoreSession component is disabled.
            // To use Playback API:
            // 1. Pause the session by disabling ARCoreSession component.
            // 2. In the next frame or later, call Session.SetPlaybackDataset(datasetFilepath)
            // where the datasetFilepath is the same one used by Recording API.
            // 3. In the next frame or later, resume the session by enabling ARCoreSession component
            // and the app will play the recorded camera stream install of using the real time
            // camera stream.
            UpdateApplicationLifecycle();

            // If the player has not touched the screen, we are done with this update.
            Touch touch;

            if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
            {
                return;
            }

            // Should not handle input if the player is pointing on UI.
            if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
            {
                return;
            }

            // Raycast against the location the player touched to search for planes.
            TrackableHit hit;
            bool         foundHit = false;

            if (InstantPlacementMenu.IsInstantPlacementEnabled())
            {
                foundHit = Frame.RaycastInstantPlacement(
                    touch.position.x, touch.position.y, 1.0f, out hit);
            }
            else
            {
                TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
                                                  TrackableHitFlags.FeaturePointWithSurfaceNormal;
                foundHit = Frame.Raycast(
                    touch.position.x, touch.position.y, raycastFilter, out hit);
            }

            if (foundHit)
            {
                // Use hit pose and camera pose to check if hittest is from the
                // back of the plane, if it is, no need to create the anchor.
                if ((hit.Trackable is DetectedPlane) &&
                    Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position,
                                hit.Pose.rotation * Vector3.up) < 0)
                {
                    Debug.Log("Hit at back of the current DetectedPlane");
                }
                else
                {
                    if (DepthMenu != null)
                    {
                        // Show depth card window if necessary.
                        DepthMenu.ConfigureDepthBeforePlacingFirstAsset();
                    }

                    // Choose the prefab based on the Trackable that got hit.
                    GameObject prefab;
                    if (hit.Trackable is InstantPlacementPoint)
                    {
                        prefab = InstantPlacementPrefab;
                    }
                    else if (hit.Trackable is FeaturePoint)
                    {
                        prefab = GameObjectPointPrefab;
                    }
                    else if (hit.Trackable is DetectedPlane)
                    {
                        DetectedPlane detectedPlane = hit.Trackable as DetectedPlane;
                        if (detectedPlane.PlaneType == DetectedPlaneType.Vertical)
                        {
                            prefab = GameObjectVerticalPlanePrefab;
                        }
                        else
                        {
                            prefab = GameObjectHorizontalPlanePrefab;
                        }
                    }
                    else
                    {
                        prefab = GameObjectHorizontalPlanePrefab;
                    }

                    // Instantiate prefab at the hit pose.
                    var gameObject = Instantiate(prefab, hit.Pose.position, hit.Pose.rotation);

                    // Compensate for the hitPose rotation facing away from the raycast (i.e.
                    // camera).
                    gameObject.transform.Rotate(0, _prefabRotation, 0, Space.Self);

                    // Create an anchor to allow ARCore to track the hitpoint as understanding of
                    // the physical world evolves.
                    var anchor = hit.Trackable.CreateAnchor(hit.Pose);

                    // Make game object a child of the anchor.
                    gameObject.transform.parent = anchor.transform;

                    // Initialize Instant Placement Effect.
                    if (hit.Trackable is InstantPlacementPoint)
                    {
                        gameObject.GetComponentInChildren <InstantPlacementEffect>()
                        .InitializeWithTrackable(hit.Trackable);
                    }
                }
            }
        }
Example #25
0
 /// 法線と一点から平面を作成
 public GeometryPlane( Vector3 prmNor, Vector3 pos )
 {
     Nor	= prmNor.Normalize();
     D	= prmNor.Dot( pos ) * -1;
 }
                /// <summary>
                /// Gets weighting values from anipal's Eye module when enable eye callback function.
                /// </summary>
                /// <param name="shapes">Weighting values obtained from anipal's Eye module.</param>
                /// <param name="eye_data">ViveSR.anipal.Eye.EyeData. </param>
                /// <returns>Indicates whether the values received are new.</returns>\
                ///
                public static bool GetEyeWeightings(out Dictionary <EyeShape, float> shapes, EyeData eye_data)
                {
                    float[]   openness      = new float[2];
                    bool[]    valid         = new bool[2];
                    Vector2[] pupilPosition = new Vector2[2];

                    foreach (EyeIndex index in (EyeIndex[])Enum.GetValues(typeof(EyeIndex)))
                    {
                        GetEyeOpenness(index, out openness[(int)index], eye_data);
                        valid[(int)index] = GetPupilPosition(index, out pupilPosition[(int)index]);
                    }

                    float[] weighting_up = new float[3] {
                        Mathf.Max(pupilPosition[(int)GazeIndex.LEFT].y, 0f), Mathf.Max(pupilPosition[(int)GazeIndex.RIGHT].y, 0f), 0
                    };
                    float[] weighting_down = new float[3] {
                        Mathf.Max(-pupilPosition[(int)GazeIndex.LEFT].y, 0f), Mathf.Max(-pupilPosition[(int)GazeIndex.RIGHT].y, 0f), 0
                    };
                    float[] weighting_left = new float[3] {
                        Mathf.Max(-pupilPosition[(int)GazeIndex.LEFT].x, 0f), Mathf.Max(-pupilPosition[(int)GazeIndex.RIGHT].x, 0f), 0
                    };
                    float[] weighting_right = new float[3] {
                        Mathf.Max(pupilPosition[(int)GazeIndex.LEFT].x, 0f), Mathf.Max(pupilPosition[(int)GazeIndex.RIGHT].x, 0f), 0
                    };
                    weighting_up[(int)GazeIndex.COMBINE]    = (weighting_up[(int)GazeIndex.LEFT] + weighting_up[(int)GazeIndex.RIGHT]) / 2;
                    weighting_down[(int)GazeIndex.COMBINE]  = (weighting_down[(int)GazeIndex.LEFT] + weighting_down[(int)GazeIndex.RIGHT]) / 2;
                    weighting_left[(int)GazeIndex.COMBINE]  = (weighting_left[(int)GazeIndex.LEFT] + weighting_left[(int)GazeIndex.RIGHT]) / 2;
                    weighting_right[(int)GazeIndex.COMBINE] = (weighting_right[(int)GazeIndex.LEFT] + weighting_right[(int)GazeIndex.RIGHT]) / 2;

                    foreach (EyeShape index in (EyeShape[])Enum.GetValues(typeof(EyeShape)))
                    {
                        Weightings[index] = 0;
                    }
                    Weightings[EyeShape.Eye_Left_Blink]  = 1 - openness[(int)EyeIndex.LEFT];
                    Weightings[EyeShape.Eye_Right_Blink] = 1 - openness[(int)EyeIndex.RIGHT];

                    if (valid[(int)EyeIndex.LEFT] && valid[(int)EyeIndex.RIGHT])
                    {
                        Ray gaze_ray = new Ray();
                        GetGazeRay(GazeIndex.COMBINE, out gaze_ray, eye_data);
                        Vector3 gaze_direction = gaze_ray.direction - gaze_ray.origin;
                        gaze_direction.x = 0.0f;
                        Vector3 gaze_direction_normalized = gaze_direction.normalized;
                        Vector3 gaze_axis_z = Vector3.forward;
                        float   y_weight    = Mathf.Acos(Vector3.Dot(gaze_direction_normalized, gaze_axis_z));

                        Weightings[EyeShape.Eye_Left_Up]    = gaze_direction_normalized.y < 0 ? 0 : y_weight;
                        Weightings[EyeShape.Eye_Left_Down]  = gaze_direction_normalized.y < 0 ? y_weight : 0;
                        Weightings[EyeShape.Eye_Left_Left]  = weighting_left[(int)GazeIndex.COMBINE];
                        Weightings[EyeShape.Eye_Left_Right] = weighting_right[(int)GazeIndex.COMBINE];
                        Weightings[EyeShape.Eye_Left_Wide]  = Weightings[EyeShape.Eye_Left_Up];

                        Weightings[EyeShape.Eye_Right_Up]    = gaze_direction_normalized.y < 0 ? 0 : y_weight;
                        Weightings[EyeShape.Eye_Right_Down]  = gaze_direction_normalized.y < 0 ? y_weight : 0;
                        Weightings[EyeShape.Eye_Right_Left]  = weighting_left[(int)GazeIndex.COMBINE];
                        Weightings[EyeShape.Eye_Right_Right] = weighting_right[(int)GazeIndex.COMBINE];
                        Weightings[EyeShape.Eye_Right_Wide]  = Weightings[EyeShape.Eye_Right_Up];
                    }
                    else if (valid[(int)EyeIndex.LEFT])
                    {
                        Ray gaze_ray = new Ray();
                        GetGazeRay(GazeIndex.LEFT, out gaze_ray, eye_data);
                        Vector3 gaze_direction = gaze_ray.direction - gaze_ray.origin;
                        gaze_direction.x = 0.0f;
                        Vector3 gaze_direction_normalized = gaze_direction.normalized;
                        Vector3 gaze_axis_z = Vector3.forward;
                        float   y_weight    = Mathf.Acos(Vector3.Dot(gaze_direction_normalized, gaze_axis_z));

                        Weightings[EyeShape.Eye_Left_Up]    = gaze_direction_normalized.y < 0 ? 0 : y_weight;
                        Weightings[EyeShape.Eye_Left_Down]  = gaze_direction_normalized.y < 0 ? y_weight : 0;
                        Weightings[EyeShape.Eye_Left_Left]  = weighting_left[(int)GazeIndex.LEFT];
                        Weightings[EyeShape.Eye_Left_Right] = weighting_right[(int)GazeIndex.LEFT];
                        Weightings[EyeShape.Eye_Left_Wide]  = Weightings[EyeShape.Eye_Left_Up];
                    }
                    else if (valid[(int)EyeIndex.RIGHT])
                    {
                        Ray gaze_ray = new Ray();
                        GetGazeRay(GazeIndex.RIGHT, out gaze_ray, eye_data);
                        Vector3 gaze_direction = gaze_ray.direction - gaze_ray.origin;
                        gaze_direction.x = 0.0f;
                        Vector3 gaze_direction_normalized = gaze_direction.normalized;
                        Vector3 gaze_axis_z = Vector3.forward;
                        float   y_weight    = Mathf.Acos(Vector3.Dot(gaze_direction_normalized, gaze_axis_z));

                        Weightings[EyeShape.Eye_Right_Up]    = gaze_direction_normalized.y < 0 ? 0 : y_weight;
                        Weightings[EyeShape.Eye_Right_Down]  = gaze_direction_normalized.y < 0 ? y_weight : 0;
                        Weightings[EyeShape.Eye_Right_Left]  = weighting_left[(int)GazeIndex.RIGHT];
                        Weightings[EyeShape.Eye_Right_Right] = weighting_right[(int)GazeIndex.RIGHT];
                        Weightings[EyeShape.Eye_Right_Wide]  = Weightings[EyeShape.Eye_Right_Up];
                    }
                    shapes = Weightings;
                    return(true);
                }
Example #27
0
 private static bool RayEnters(Vector3 rayN, Vector3 triN)
 {
     if (rayN.Dot(triN) < 0) return true;
     return false;
 }
Example #28
0
        /// <summary>
        /// Query the possible connections for this field
        /// </summary>
        /// <param name="match">Out parameter that signifies the type of match (ignore, reject or connect)</param>
        /// <param name="bothkinds">Optional boolean to specify whether we want to check for both connection field kinds</param>
        /// <param name="onlyConnectTo">An optional filter field if you only want to check connections on specific fields</param>
        /// <returns>A list of tuples for the possible connections</returns>
        public HashSet <(Connection, Connection)> QueryConnections(out Connection.ConnectionMatch match, bool bothkinds = false, ICollection <ConnectionField> onlyConnectTo = null)
        {
            LayerMask mask;

            if (bothkinds)
            {
                mask = LayerMask.GetMask(GetLayer(FieldKind.receptor), GetLayer(FieldKind.connector));
            }
            else
            {
                var opposite = kind == FieldKind.connector ? FieldKind.receptor : FieldKind.connector;
                mask = LayerMask.GetMask(GetLayer(opposite));
            }

            HashSet <(Connection, Connection)> validConnections = new HashSet <(Connection, Connection)>();

            match = Connection.ConnectionMatch.ignore;

            // PhysicsScene
            var physicsScene = gameObject.scene.GetPhysicsScene();
            var size         = new Vector3((gridSize.x + 1) * BrickBuildingUtility.LU_5, BrickBuildingUtility.LU_1 * 2, (gridSize.y + 1) * BrickBuildingUtility.LU_5);
            var center       = new Vector3((size.x - BrickBuildingUtility.LU_5) * -0.5f, 0.0f, (size.z - BrickBuildingUtility.LU_5) * 0.5f);

            var hits = physicsScene.OverlapBox(transform.TransformPoint(center), size * 0.5f, BrickBuildingUtility.colliderBuffer, transform.rotation, mask, QueryTriggerInteraction.Collide);

            for (var i = 0; i < hits; i++)
            {
                var overlap = BrickBuildingUtility.colliderBuffer[i];
                var field   = overlap.GetComponent <ConnectionField>();
                if (field == null || field == this)
                {
                    continue;
                }

                if (onlyConnectTo != null && !onlyConnectTo.Contains(field))
                {
                    continue;
                }

                if (Mathf.Abs(Vector3.Dot(field.transform.up, transform.up)) < 0.95f)
                {
                    continue;
                }

                if (!GetOverlap(field, this, out Vector2Int min, out Vector2Int max))
                {
                    continue;
                }

                for (var x = min.x; x < max.x + 1; x++)
                {
                    for (var z = min.y; z < max.y + 1; z++)
                    {
                        var localPos        = new Vector3(x * BrickBuildingUtility.LU_5, 0.0f, z * BrickBuildingUtility.LU_5);
                        var fieldConnection = field.GetConnectionAt(ConnectionField.ToGridPos(localPos));
                        if (fieldConnection != null && !field.HasConnection(fieldConnection))
                        {
                            var worldPos   = field.GetPosition(fieldConnection);
                            var connection = GetConnectionAt(worldPos);
                            if (connection != null && !HasConnection(connection))
                            {
                                // Note: ConnectionValid checks both rejection and distance (position + rotation) so we need
                                //       to make sure we take care of both in case of false.
                                if (!Connection.ConnectionValid(fieldConnection, connection, out Connection.ConnectionMatch pairMatch))
                                {
                                    if (pairMatch != Connection.ConnectionMatch.reject)
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        match = pairMatch;
                                        validConnections.Clear();
                                        return(validConnections);
                                    }
                                }

                                if (pairMatch == Connection.ConnectionMatch.connect)
                                {
                                    validConnections.Add((connection, fieldConnection));
                                }
                            }
                        }
                    }
                }
            }

            match = Connection.ConnectionMatch.connect;
            return(validConnections);
        }
Example #29
0
 public static void Reflect(ref Vector3 vector, ref Vector3 planeNormal, out Vector3 result)
 {
     result = vector - (planeNormal * vector.Dot(planeNormal) * 2);
 }
Example #30
0
        public void VoxelizeInput(Pathfinding.Util.GraphTransform graphTransform, Bounds graphSpaceBounds)
        {
            AstarProfiler.StartProfile("Build Navigation Mesh");

            AstarProfiler.StartProfile("Voxelizing - Step 1");

            // Transform from voxel space to graph space.
            // then scale from voxel space (one unit equals one voxel)
            // Finally add min
            Matrix4x4 voxelMatrix = Matrix4x4.TRS(graphSpaceBounds.min, Quaternion.identity, Vector3.one) * Matrix4x4.Scale(new Vector3(cellSize, cellHeight, cellSize));

            transformVoxel2Graph = new Pathfinding.Util.GraphTransform(voxelMatrix);

            // Transform from voxel space to world space
            // add half a voxel to fix rounding
            transform = graphTransform * voxelMatrix * Matrix4x4.TRS(new Vector3(0.5f, 0, 0.5f), Quaternion.identity, Vector3.one);

            int maximumVoxelYCoord = (int)(graphSpaceBounds.size.y / cellHeight);

            AstarProfiler.EndProfile("Voxelizing - Step 1");

            AstarProfiler.StartProfile("Voxelizing - Step 2 - Init");

            // Cosine of the slope limit in voxel space (some tweaks are needed because the voxel space might be stretched out along the y axis)
            float slopeLimit = Mathf.Cos(Mathf.Atan(Mathf.Tan(maxSlope * Mathf.Deg2Rad) * (cellSize / cellHeight)));

            // Temporary arrays used for rasterization
            var clipperOrig = new VoxelPolygonClipper(3);
            var clipperX1   = new VoxelPolygonClipper(7);
            var clipperX2   = new VoxelPolygonClipper(7);
            var clipperZ1   = new VoxelPolygonClipper(7);
            var clipperZ2   = new VoxelPolygonClipper(7);

            if (inputMeshes == null)
            {
                throw new System.NullReferenceException("inputMeshes not set");
            }

            // Find the largest lengths of vertex arrays and check for meshes which can be skipped
            int maxVerts = 0;

            for (int m = 0; m < inputMeshes.Count; m++)
            {
                maxVerts = System.Math.Max(inputMeshes[m].vertices.Length, maxVerts);
            }

            // Create buffer, here vertices will be stored multiplied with the local-to-voxel-space matrix
            var verts = new Vector3[maxVerts];

            AstarProfiler.EndProfile("Voxelizing - Step 2 - Init");

            AstarProfiler.StartProfile("Voxelizing - Step 2");

            // This loop is the hottest place in the whole rasterization process
            // it usually accounts for around 50% of the time
            for (int m = 0; m < inputMeshes.Count; m++)
            {
                RasterizationMesh mesh = inputMeshes[m];
                var meshMatrix         = mesh.matrix;

                // Flip the orientation of all faces if the mesh is scaled in such a way
                // that the face orientations would change
                // This happens for example if a mesh has a negative scale along an odd number of axes
                // e.g it happens for the scale (-1, 1, 1) but not for (-1, -1, 1) or (1,1,1)
                var flipOrientation = VectorMath.ReversesFaceOrientations(meshMatrix);

                Vector3[] vs         = mesh.vertices;
                int[]     tris       = mesh.triangles;
                int       trisLength = mesh.numTriangles;

                // Transform vertices first to world space and then to voxel space
                for (int i = 0; i < vs.Length; i++)
                {
                    verts[i] = transform.InverseTransform(meshMatrix.MultiplyPoint3x4(vs[i]));
                }

                int mesharea = mesh.area;

                for (int i = 0; i < trisLength; i += 3)
                {
                    Vector3 p1 = verts[tris[i]];
                    Vector3 p2 = verts[tris[i + 1]];
                    Vector3 p3 = verts[tris[i + 2]];

                    if (flipOrientation)
                    {
                        var tmp = p1;
                        p1 = p3;
                        p3 = tmp;
                    }

                    int minX = (int)(Utility.Min(p1.x, p2.x, p3.x));
                    int minZ = (int)(Utility.Min(p1.z, p2.z, p3.z));

                    int maxX = (int)System.Math.Ceiling(Utility.Max(p1.x, p2.x, p3.x));
                    int maxZ = (int)System.Math.Ceiling(Utility.Max(p1.z, p2.z, p3.z));

                    minX = Mathf.Clamp(minX, 0, voxelArea.width - 1);
                    maxX = Mathf.Clamp(maxX, 0, voxelArea.width - 1);
                    minZ = Mathf.Clamp(minZ, 0, voxelArea.depth - 1);
                    maxZ = Mathf.Clamp(maxZ, 0, voxelArea.depth - 1);

                    // Check if the mesh is completely out of bounds
                    if (minX >= voxelArea.width || minZ >= voxelArea.depth || maxX <= 0 || maxZ <= 0)
                    {
                        continue;
                    }

                    Vector3 normal;

                    int area;

                    //AstarProfiler.StartProfile ("Rasterize...");

                    normal = Vector3.Cross(p2 - p1, p3 - p1);

                    float cosSlopeAngle = Vector3.Dot(normal.normalized, Vector3.up);

                    if (cosSlopeAngle < slopeLimit)
                    {
                        area = UnwalkableArea;
                    }
                    else
                    {
                        area = 1 + mesharea;
                    }

                    clipperOrig[0] = p1;
                    clipperOrig[1] = p2;
                    clipperOrig[2] = p3;
                    clipperOrig.n  = 3;

                    for (int x = minX; x <= maxX; x++)
                    {
                        clipperOrig.ClipPolygonAlongX(ref clipperX1, 1f, -x + 0.5f);

                        if (clipperX1.n < 3)
                        {
                            continue;
                        }

                        clipperX1.ClipPolygonAlongX(ref clipperX2, -1F, x + 0.5F);

                        if (clipperX2.n < 3)
                        {
                            continue;
                        }

                        float clampZ1 = clipperX2.z[0];
                        float clampZ2 = clipperX2.z[0];
                        for (int q = 1; q < clipperX2.n; q++)
                        {
                            float val = clipperX2.z[q];
                            clampZ1 = System.Math.Min(clampZ1, val);
                            clampZ2 = System.Math.Max(clampZ2, val);
                        }

                        int clampZ1I = Mathf.Clamp((int)System.Math.Round(clampZ1), 0, voxelArea.depth - 1);
                        int clampZ2I = Mathf.Clamp((int)System.Math.Round(clampZ2), 0, voxelArea.depth - 1);

                        for (int z = clampZ1I; z <= clampZ2I; z++)
                        {
                            clipperX2.ClipPolygonAlongZWithYZ(ref clipperZ1, 1F, -z + 0.5F);

                            if (clipperZ1.n < 3)
                            {
                                continue;
                            }

                            clipperZ1.ClipPolygonAlongZWithY(ref clipperZ2, -1F, z + 0.5F);
                            if (clipperZ2.n < 3)
                            {
                                continue;
                            }

                            float sMin = clipperZ2.y[0];
                            float sMax = clipperZ2.y[0];
                            for (int q = 1; q < clipperZ2.n; q++)
                            {
                                float val = clipperZ2.y[q];
                                sMin = System.Math.Min(sMin, val);
                                sMax = System.Math.Max(sMax, val);
                            }

                            int maxi = (int)System.Math.Ceiling(sMax);

                            // Skip span if below or above the bounding box
                            if (maxi >= 0 && sMin <= maximumVoxelYCoord)
                            {
                                // Make sure mini >= 0
                                int mini = System.Math.Max(0, (int)sMin);

                                // Make sure the span is at least 1 voxel high
                                maxi = System.Math.Max(mini + 1, maxi);

                                voxelArea.AddLinkedSpan(z * voxelArea.width + x, (uint)mini, (uint)maxi, area, voxelWalkableClimb);
                            }
                        }
                    }
                }
                //AstarProfiler.EndFastProfile(0);
                //AstarProfiler.EndProfile ("Rasterize...");
            }
            AstarProfiler.EndProfile("Voxelizing - Step 2");
        }
Example #31
0
		internal void TransformPlane( float[] norm, ref float dist )
		{
			TransformVector( norm, true );
			dist *= this.options.scale;
			var normal = new Vector3( norm[ 0 ], norm[ 1 ], norm[ 2 ] );
			Vector3 point = normal*dist;
			point += this.options.move;
			dist = normal.Dot( point );
		}
    static void SmoothNormalToColor()
    {
        string NewMeshPath = "Assets/Models/Yuanshen/";;

        var trans = Selection.activeTransform;

        NewMeshPath += trans.name + "_" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + ".asset";
        // 获取Mesh
        Mesh mesh = new Mesh();

        if (trans.GetComponent <SkinnedMeshRenderer>())
        {
            mesh = trans.GetComponent <SkinnedMeshRenderer>().sharedMesh;
        }
        if (trans.GetComponent <MeshFilter>())
        {
            mesh = trans.GetComponent <MeshFilter>().sharedMesh;
        }
        Debug.Log(mesh.name);


        // 计算进度
        int sum   = 6 * (mesh.vertices.Length / 3) + mesh.normals.Length;
        int count = 0;


        // 声明一个Vector3数组,长度与mesh.normals一样,用于存放
        // 与mesh.vertices中顶点一一对应的光滑处理后的法线值
        Vector3[] smoothedNormals = new Vector3[mesh.normals.Length];

        // 空间换时间 (存下每个法线的相同的顶点索引)  其实就是真正的共享顶点 立方体的话因该是24 / 3=8个共享顶点。
        // 这里用到了hash表 (可以去领扣刷刷hash表相关的题,游戏还是会用到的)
        Dictionary <Vector3, List <int> > vertexDic = new Dictionary <Vector3, List <int> >();

        for (int i = 0; i < mesh.vertices.Length; i++)
        {
            float jd = count++ / (float)sum;
            EditorUtility.DisplayProgressBar("smooth", count.ToString(), jd);


            if (!vertexDic.ContainsKey(mesh.vertices[i]))
            {
                List <int> vertexIndexs = new List <int>();
                vertexIndexs.Add(i);
                vertexDic.Add(mesh.vertices[i], vertexIndexs);
            }
            else
            {
                vertexDic[mesh.vertices[i]].Add(i);
            }
        }
        // 平均化每个顶点
        foreach (var item in vertexDic)
        {
            float jd = count++ / (float)sum;
            EditorUtility.DisplayProgressBar("smooth", count.ToString(), jd);

            Vector3 smoothedNormal = new Vector3(0, 0, 0);
            foreach (var index in item.Value)
            {
                smoothedNormal += mesh.normals[index];
            }
            smoothedNormal.Normalize();
            foreach (var index in item.Value)
            {
                smoothedNormals[index] = smoothedNormal;
            }
        }

        // 新建一个颜色数组把光滑处理后的法线值存入其中
        Color[] meshColors = new Color[smoothedNormals.Length];
        for (int i = 0; i < smoothedNormals.Length; i++)
        {
            float jd = count++ / (float)sum;
            EditorUtility.DisplayProgressBar("smooth", count.ToString(), jd);

            // 构建模型空间→切线空间的转换矩阵
            Vector3[] OtoTMatrix = new Vector3[3];
            OtoTMatrix[0] = new Vector3(mesh.tangents[i].x, mesh.tangents[i].y, mesh.tangents[i].z);
            OtoTMatrix[1] = Vector3.Cross(mesh.normals[i], OtoTMatrix[0]) * mesh.tangents[i].w;
            OtoTMatrix[2] = mesh.normals[i];

            // 将meshNormals数组中的法线值一一与矩阵相乘,求得切线空间下的法线值
            Vector3 tNormal;
            tNormal            = Vector3.zero;
            tNormal.x          = Vector3.Dot(OtoTMatrix[0], smoothedNormals[i]);
            tNormal.y          = Vector3.Dot(OtoTMatrix[1], smoothedNormals[i]);
            tNormal.z          = Vector3.Dot(OtoTMatrix[2], smoothedNormals[i]);
            smoothedNormals[i] = tNormal;

            meshColors[i].r = smoothedNormals[i].x * 0.5f + 0.5f;
            meshColors[i].g = smoothedNormals[i].y * 0.5f + 0.5f;
            meshColors[i].b = smoothedNormals[i].z * 0.5f + 0.5f;
            if (mesh.colors.Length != 0)
            {
                meshColors[i].a = mesh.colors[i].a;
            }
        }

        //新建一个mesh,将之前mesh的所有信息copy过去
        Mesh newMesh = Object.Instantiate(mesh) as Mesh;

        //将新模型的颜色赋值为计算好的颜色
        newMesh.colors = meshColors;
        //newMesh.colors32 = mesh.colors32;
        //将新mesh保存为.asset文件,路径可以是"Assets/Character/Shader/VertexColorTest/TestMesh2.asset"
        AssetDatabase.CreateAsset(newMesh, NewMeshPath);
        AssetDatabase.SaveAssets();
        Debug.Log("Done");


        EditorUtility.ClearProgressBar();
    }
Example #33
0
 /// <summary>
 ///		Construct a plane from 3 coplanar points.
 /// </summary>
 /// <param name="point0">First point.</param>
 /// <param name="point1">Second point.</param>
 /// <param name="point2">Third point.</param>
 public Plane(Vector3 point0, Vector3 point1, Vector3 point2)
 {
     Vector3 edge1 = point1 - point0;
     Vector3 edge2 = point2 - point0;
     Normal = edge1.Cross(edge2);
     Normal.Normalize();
     D = -Normal.Dot(point0);
 }
        public static Vector3 GetIntersectionRayPlane(FPlane plane, FRay ray)
        {
            Vector3 result;
            Vector3 planeNormal = new Vector3(plane.X, plane.Y, plane.Z);
            float   timeParam   = (plane.D + (Vector3.Dot(planeNormal, ray.StartPosition))) / Vector3.Dot(planeNormal, ray.Direction);

            result = ray.StartPosition + ray.Direction * timeParam;
            return(result);
        }
Example #35
0
    /// <summary>
    /// Draw the on-screen selection, knobs, and handle all interaction logic.
    /// </summary>

    public void OnSceneGUI()
    {
        if (Selection.objects.Length > 1)
        {
            return;
        }
        NGUIEditorTools.HideMoveTool(true);
        if (!UIWidget.showHandles)
        {
            return;
        }

        mWidget = target as UIWidget;

        Transform t = mWidget.cachedTransform;

        Event     e    = Event.current;
        int       id   = GUIUtility.GetControlID(s_Hash, FocusType.Passive);
        EventType type = e.GetTypeForControl(id);

        Action actionUnderMouse = mAction;

        Vector3[] handles = GetHandles(mWidget.worldCorners);

        NGUIHandles.DrawShadowedLine(handles, handles[0], handles[1], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[1], handles[2], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[2], handles[3], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[0], handles[3], handlesColor);

        // If the widget is anchored, draw the anchors
        if (mWidget.isAnchored)
        {
            DrawAnchorHandle(mWidget.leftAnchor, mWidget.cachedTransform, handles, 0, id);
            DrawAnchorHandle(mWidget.topAnchor, mWidget.cachedTransform, handles, 1, id);
            DrawAnchorHandle(mWidget.rightAnchor, mWidget.cachedTransform, handles, 2, id);
            DrawAnchorHandle(mWidget.bottomAnchor, mWidget.cachedTransform, handles, 3, id);
        }

        if (type == EventType.Repaint)
        {
            bool showDetails = (mAction == UIWidgetInspector.Action.Scale) || NGUISettings.drawGuides;
            if (mAction == UIWidgetInspector.Action.None && e.modifiers == EventModifiers.Control)
            {
                showDetails = true;
            }
            if (NGUITools.GetActive(mWidget) && mWidget.parent == null)
            {
                showDetails = true;
            }
            if (showDetails)
            {
                NGUIHandles.DrawSize(handles, mWidget.width, mWidget.height);
            }
        }

        // Presence of the legacy stretch component prevents resizing
        bool canResize = (mWidget.GetComponent <UIStretch>() == null);

        bool[] resizable = new bool[8];

        resizable[4] = canResize;               // left
        resizable[5] = canResize;               // top
        resizable[6] = canResize;               // right
        resizable[7] = canResize;               // bottom

        UILabel lbl = mWidget as UILabel;

        if (lbl != null)
        {
            if (lbl.overflowMethod == UILabel.Overflow.ResizeFreely)
            {
                resizable[4] = false;                   // left
                resizable[5] = false;                   // top
                resizable[6] = false;                   // right
                resizable[7] = false;                   // bottom
            }
            else if (lbl.overflowMethod == UILabel.Overflow.ResizeHeight)
            {
                resizable[5] = false;                   // top
                resizable[7] = false;                   // bottom
            }
        }

        if (mWidget.keepAspectRatio == UIWidget.AspectRatioSource.BasedOnHeight)
        {
            resizable[4] = false;
            resizable[6] = false;
        }
        else if (mWidget.keepAspectRatio == UIWidget.AspectRatioSource.BasedOnWidth)
        {
            resizable[5] = false;
            resizable[7] = false;
        }

        resizable[0] = resizable[7] && resizable[4];         // bottom-left
        resizable[1] = resizable[5] && resizable[4];         // top-left
        resizable[2] = resizable[5] && resizable[6];         // top-right
        resizable[3] = resizable[7] && resizable[6];         // bottom-right

        UIWidget.Pivot pivotUnderMouse = GetPivotUnderMouse(handles, e, resizable, true, ref actionUnderMouse);

        switch (type)
        {
        case EventType.Repaint:
        {
            Vector3 v0 = HandleUtility.WorldToGUIPoint(handles[0]);
            Vector3 v2 = HandleUtility.WorldToGUIPoint(handles[2]);

            if ((v2 - v0).magnitude > 60f)
            {
                Vector3 v1 = HandleUtility.WorldToGUIPoint(handles[1]);
                Vector3 v3 = HandleUtility.WorldToGUIPoint(handles[3]);

                Handles.BeginGUI();
                {
                    for (int i = 0; i < 4; ++i)
                    {
                        DrawKnob(handles[i], mWidget.pivot == pivotPoints[i], resizable[i], id);
                    }

                    if ((v1 - v0).magnitude > 80f)
                    {
                        if (mWidget.leftAnchor.target == null || mWidget.leftAnchor.absolute != 0)
                        {
                            DrawKnob(handles[4], mWidget.pivot == pivotPoints[4], resizable[4], id);
                        }

                        if (mWidget.rightAnchor.target == null || mWidget.rightAnchor.absolute != 0)
                        {
                            DrawKnob(handles[6], mWidget.pivot == pivotPoints[6], resizable[6], id);
                        }
                    }

                    if ((v3 - v0).magnitude > 80f)
                    {
                        if (mWidget.topAnchor.target == null || mWidget.topAnchor.absolute != 0)
                        {
                            DrawKnob(handles[5], mWidget.pivot == pivotPoints[5], resizable[5], id);
                        }

                        if (mWidget.bottomAnchor.target == null || mWidget.bottomAnchor.absolute != 0)
                        {
                            DrawKnob(handles[7], mWidget.pivot == pivotPoints[7], resizable[7], id);
                        }
                    }
                }
                Handles.EndGUI();
            }
        }
        break;

        case EventType.MouseDown:
        {
            if (actionUnderMouse != Action.None)
            {
                mStartMouse     = e.mousePosition;
                mAllowSelection = true;

                if (e.button == 1)
                {
                    if (e.modifiers == 0)
                    {
                        GUIUtility.hotControl = GUIUtility.keyboardControl = id;
                        e.Use();
                    }
                }
                else if (e.button == 0 && actionUnderMouse != Action.None && Raycast(handles, out mStartDrag))
                {
                    mWorldPos      = t.position;
                    mLocalPos      = t.localPosition;
                    mStartRot      = t.localRotation.eulerAngles;
                    mStartDir      = mStartDrag - t.position;
                    mStartWidth    = mWidget.width;
                    mStartHeight   = mWidget.height;
                    mStartLeft.x   = mWidget.leftAnchor.relative;
                    mStartLeft.y   = mWidget.leftAnchor.absolute;
                    mStartRight.x  = mWidget.rightAnchor.relative;
                    mStartRight.y  = mWidget.rightAnchor.absolute;
                    mStartBottom.x = mWidget.bottomAnchor.relative;
                    mStartBottom.y = mWidget.bottomAnchor.absolute;
                    mStartTop.x    = mWidget.topAnchor.relative;
                    mStartTop.y    = mWidget.topAnchor.absolute;

                    mDragPivot            = pivotUnderMouse;
                    mActionUnderMouse     = actionUnderMouse;
                    GUIUtility.hotControl = GUIUtility.keyboardControl = id;
                    e.Use();
                }
            }
        }
        break;

        case EventType.MouseDrag:
        {
            // Prevent selection once the drag operation begins
            bool dragStarted = (e.mousePosition - mStartMouse).magnitude > 3f;
            if (dragStarted)
            {
                mAllowSelection = false;
            }

            if (GUIUtility.hotControl == id)
            {
                e.Use();

                if (mAction != Action.None || mActionUnderMouse != Action.None)
                {
                    Vector3 pos;

                    if (Raycast(handles, out pos))
                    {
                        if (mAction == Action.None && mActionUnderMouse != Action.None)
                        {
                            // Wait until the mouse moves by more than a few pixels
                            if (dragStarted)
                            {
                                if (mActionUnderMouse == Action.Move)
                                {
                                    NGUISnap.Recalculate(mWidget);
                                }
                                else if (mActionUnderMouse == Action.Rotate)
                                {
                                    mStartRot = t.localRotation.eulerAngles;
                                    mStartDir = mStartDrag - t.position;
                                }
                                else if (mActionUnderMouse == Action.Scale)
                                {
                                    mStartWidth  = mWidget.width;
                                    mStartHeight = mWidget.height;
                                    mDragPivot   = pivotUnderMouse;
                                }
                                mAction = actionUnderMouse;
                            }
                        }

                        if (mAction != Action.None)
                        {
                            NGUIEditorTools.RegisterUndo("Change Rect", t);
                            NGUIEditorTools.RegisterUndo("Change Rect", mWidget);

                            // Reset the widget before adjusting anything
                            t.position     = mWorldPos;
                            mWidget.width  = mStartWidth;
                            mWidget.height = mStartHeight;
                            mWidget.leftAnchor.Set(mStartLeft.x, mStartLeft.y);
                            mWidget.rightAnchor.Set(mStartRight.x, mStartRight.y);
                            mWidget.bottomAnchor.Set(mStartBottom.x, mStartBottom.y);
                            mWidget.topAnchor.Set(mStartTop.x, mStartTop.y);

                            if (mAction == Action.Move)
                            {
                                // Move the widget
                                t.position = mWorldPos + (pos - mStartDrag);
                                Vector3 after = t.localPosition;

                                bool      snapped = false;
                                Transform parent  = t.parent;

                                if (parent != null)
                                {
                                    UIGrid grid = parent.GetComponent <UIGrid>();

                                    if (grid != null && grid.arrangement == UIGrid.Arrangement.CellSnap)
                                    {
                                        snapped = true;
                                        if (grid.cellWidth > 0)
                                        {
                                            after.x = Mathf.Round(after.x / grid.cellWidth) * grid.cellWidth;
                                        }
                                        if (grid.cellHeight > 0)
                                        {
                                            after.y = Mathf.Round(after.y / grid.cellHeight) * grid.cellHeight;
                                        }
                                    }
                                }

                                if (!snapped)
                                {
                                    // Snap the widget
                                    after = NGUISnap.Snap(after, mWidget.localCorners, e.modifiers != EventModifiers.Control);
                                }

                                // Calculate the final delta
                                Vector3 localDelta = (after - mLocalPos);

                                // Restore the position
                                t.position = mWorldPos;

                                // Adjust the widget by the delta
                                NGUIMath.MoveRect(mWidget, localDelta.x, localDelta.y);
                            }
                            else if (mAction == Action.Rotate)
                            {
                                Vector3 dir   = pos - t.position;
                                float   angle = Vector3.Angle(mStartDir, dir);

                                if (angle > 0f)
                                {
                                    float dot = Vector3.Dot(Vector3.Cross(mStartDir, dir), t.forward);
                                    if (dot < 0f)
                                    {
                                        angle = -angle;
                                    }
                                    angle = mStartRot.z + angle;
                                    angle = (NGUISnap.allow && e.modifiers != EventModifiers.Control) ?
                                            Mathf.Round(angle / 15f) * 15f : Mathf.Round(angle);
                                    t.localRotation = Quaternion.Euler(mStartRot.x, mStartRot.y, angle);
                                }
                            }
                            else if (mAction == Action.Scale)
                            {
                                // Move the widget
                                t.position = mWorldPos + (pos - mStartDrag);

                                // Calculate the final delta
                                Vector3 localDelta = (t.localPosition - mLocalPos);

                                // Restore the position
                                t.position = mWorldPos;

                                // Adjust the widget's position and scale based on the delta, restricted by the pivot
                                NGUIMath.ResizeWidget(mWidget, mDragPivot, localDelta.x, localDelta.y, 2, 2);
                                ReEvaluateAnchorType();
                            }
                        }
                    }
                }
            }
        }
        break;

        case EventType.MouseUp:
        {
            if (e.button == 2)
            {
                break;
            }
            if (GUIUtility.hotControl == id)
            {
                GUIUtility.hotControl      = 0;
                GUIUtility.keyboardControl = 0;

                if (e.button < 2)
                {
                    bool handled = false;

                    if (e.button == 1)
                    {
                        // Right-click: Open a context menu listing all widgets underneath
                        NGUIEditorTools.ShowSpriteSelectionMenu(e.mousePosition);
                        handled = true;
                    }
                    else if (mAction == Action.None)
                    {
                        if (mAllowSelection)
                        {
                            // Left-click: Select the topmost widget
                            NGUIEditorTools.SelectWidget(e.mousePosition);
                            handled = true;
                        }
                    }
                    else
                    {
                        // Finished dragging something
                        Vector3 pos = t.localPosition;
                        pos.x           = Mathf.Round(pos.x);
                        pos.y           = Mathf.Round(pos.y);
                        pos.z           = Mathf.Round(pos.z);
                        t.localPosition = pos;
                        handled         = true;
                    }

                    if (handled)
                    {
                        e.Use();
                    }
                }

                // Clear the actions
                mActionUnderMouse = Action.None;
                mAction           = Action.None;
            }
            else if (mAllowSelection)
            {
                List <UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition);
                if (widgets.Count > 0)
                {
                    Selection.activeGameObject = widgets[0].gameObject;
                }
            }
            mAllowSelection = true;
        }
        break;

        case EventType.KeyDown:
        {
            if (e.keyCode == KeyCode.UpArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mWidget);
                NGUIMath.MoveRect(mWidget, 0f, 1f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.DownArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mWidget);
                NGUIMath.MoveRect(mWidget, 0f, -1f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.LeftArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mWidget);
                NGUIMath.MoveRect(mWidget, -1f, 0f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.RightArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mWidget);
                NGUIMath.MoveRect(mWidget, 1f, 0f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.Escape)
            {
                if (GUIUtility.hotControl == id)
                {
                    if (mAction != Action.None)
                    {
                        Undo.PerformUndo();
                    }

                    GUIUtility.hotControl      = 0;
                    GUIUtility.keyboardControl = 0;

                    mActionUnderMouse = Action.None;
                    mAction           = Action.None;
                    e.Use();
                }
                else
                {
                    Selection.activeGameObject = null;
                }
            }
        }
        break;
        }
    }
Example #36
0
        public static void half_diff_coords_to_std_coords( double _ThetaHalf, double _PhiHalf, double _ThetaDiff, double _PhiDiff,
													ref Vector3 _In, ref Vector3 _Out )
        {
            double	SinTheta_half = Math.Sin( _ThetaHalf );
            Half.Set( Math.Cos( _PhiHalf ) * SinTheta_half, Math.Sin( _PhiHalf ) * SinTheta_half, Math.Cos( _ThetaHalf ) );

            // Build the 2 vectors representing the frame in which we can use the diff angles
            Vector3	OrthoX;
            Half.Cross( ref Normal, out OrthoX );
            if ( OrthoX.LengthSq() < 1e-6 )
                OrthoX.Set( 1, 0, 0 );
            else
                OrthoX.Normalize();

            Vector3	OrthoY;
            Half.Cross( ref OrthoX, out OrthoY );

            // Rotate using diff angles to retrieve incoming direction
            Half.Rotate( ref OrthoX, -_ThetaDiff, out Temp );
            Temp.Rotate( ref Half, _PhiDiff, out _In );

            // ...or by mirroring in "Half tangent space"
            double	MirrorX = -_In.Dot( ref OrthoX );
            double	MirrorY = -_In.Dot( ref OrthoY );
            double	z = _In.Dot( ref Half );
            _Out.Set(
                MirrorX*OrthoX.x + MirrorY*OrthoY.x + z*Half.x,
                MirrorX*OrthoX.y + MirrorY*OrthoY.y + z*Half.y,
                MirrorX*OrthoX.z + MirrorY*OrthoY.z + z*Half.z
            );

            // 			if ( _In.z < -0.5 || _Out.z < -0.5 )
            // 				throw new Exception( "RHA MAIS MERDE!" );
        }
        /// <summary>
        ///		Gets the shortest arc quaternion to rotate this vector to the destination vector. 
        /// </summary>
        /// <remarks>
        ///		Don't call this if you think the dest vector can be close to the inverse
        ///		of this vector, since then ANY axis of rotation is ok.
        ///	</remarks>
        public Quaternion GetRotationTo(Vector3 destination)
        {
            // Based on Stan Melax's article in Game Programming Gems
            Quaternion q = new Quaternion();

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

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

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

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

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

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

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

            return q;
        }
Example #38
0
        /// <summary>
        /// ホイールの移動量から
        /// ロータリーエンコーダ 回転パルス値を計算
        /// </summary>
        public void CalcWheelPosToREPulse()
        {
            const double WheelSize = 175;//172;    // ホイール直径
            const double OneRotValue = 240;   // 1回転分の分解能

            Vector3 wheelLmov, wheelRmov;

            Real signL, signR;
            // 移動量と移動方向(+,-)を求める
            {
                Quaternion rotQt = new Quaternion();
                Vector3 moveVec = new Vector3();

                rotQt.RollInDegrees = wdCarAng;
                moveVec.y = 1.0;
                moveVec = rotQt.ToRotationMatrix() * moveVec;

                // 移動差分から、移動量を求める
                wheelLmov = new Vector3(wdRL.x - wdRLOld.x,
                                                 wdRL.y - wdRLOld.y,
                                                 wdRL.z - wdRLOld.z);

                wheelRmov = new Vector3(wdRR.x - wdRROld.x,
                                                 wdRR.y - wdRROld.y,
                                                 wdRR.z - wdRROld.z);

                if (moveVec.Dot(wheelLmov) > 0.0) signL = -1.0;
                else signL = 1.0;
                if (moveVec.Dot(wheelRmov) > 0.0) signR = -1.0;
                else signR = 1.0;
            }

            // 移動量(長さ) / ホイール1回転の長さ * 1回転のパルス数
            wheelPulseL += (wheelLmov.Length / (WheelSize * Math.PI) * OneRotValue) * signL;
            wheelPulseR += (wheelRmov.Length / (WheelSize * Math.PI) * OneRotValue) * signR;
        }
Example #39
0
    Vector3 CalcViewBox(Vector3 center, Vector3 up, Vector3 forward)
    {
        /*
         * Debug.DrawLine (v3FrontTopLeft, v3FrontTopRight, Color.yellow);
         * Debug.DrawLine (v3FrontTopRight, v3FrontBottomRight, Color.yellow);
         * Debug.DrawLine (v3FrontBottomRight, v3FrontBottomLeft, Color.yellow);
         * Debug.DrawLine (v3FrontBottomLeft, v3FrontTopLeft, Color.yellow);
         */
        /*
         * Debug.DrawLine (v3FrontTopLeft, v3BackTopLeft, Color.yellow); //cross member
         * Debug.DrawLine (v3FrontTopRight, v3BackTopRight, Color.yellow); //cross member
         * Debug.DrawLine (v3FrontBottomRight, v3BackBottomRight, Color.yellow); //cross member
         * Debug.DrawLine (v3FrontBottomLeft, v3BackBottomLeft, Color.yellow); //cross member
         */
        /*
         * Debug.DrawLine (v3BackTopLeft, v3BackTopRight, Color.yellow);
         * Debug.DrawLine (v3BackTopRight, v3BackBottomRight, Color.yellow);
         * Debug.DrawLine (v3BackBottomRight, v3BackBottomLeft, Color.yellow);
         * Debug.DrawLine (v3BackBottomLeft, v3BackTopLeft, Color.yellow);
         */

        var right = Quaternion.Euler(up * 90) * forward;          //compute a right vecotr orthagonal to the camera and scene object facing vector

        //Front Top
        var dotXFTL = (Vector3.Dot(right, v3FrontTopLeft - center));
        var dotXFTR = (Vector3.Dot(right, v3FrontTopRight - center));

        var dotYFTL = (Vector3.Dot(up, v3FrontTopLeft - center));
        var dotYFTR = (Vector3.Dot(up, v3FrontTopRight - center));

        var dotZFTL = (Vector3.Dot(forward, v3FrontTopLeft - center));
        var dotZFTR = (Vector3.Dot(forward, v3FrontTopRight - center));

        //Front Bot
        var dotXFBL = (Vector3.Dot(right, v3FrontBottomLeft - center));
        var dotXFBR = (Vector3.Dot(right, v3FrontBottomRight - center));

        var dotYFBL = (Vector3.Dot(up, v3FrontBottomLeft - center));
        var dotYFBR = (Vector3.Dot(up, v3FrontBottomRight - center));

        var dotZFBL = (Vector3.Dot(forward, v3FrontBottomLeft - center));
        var dotZFBR = (Vector3.Dot(forward, v3FrontBottomRight - center));

        //Back Top
        var dotXBTL = (Vector3.Dot(right, v3BackTopLeft - center));
        var dotXBTR = (Vector3.Dot(right, v3BackTopRight - center));

        var dotYBTL = (Vector3.Dot(up, v3BackTopLeft - center));
        var dotYBTR = (Vector3.Dot(up, v3BackTopRight - center));

        var dotZBTL = (Vector3.Dot(forward, v3BackTopLeft - center));
        var dotZBTR = (Vector3.Dot(forward, v3BackTopRight - center));

        //Back Bot
        var dotXBBL = (Vector3.Dot(right, v3BackBottomLeft - center));
        var dotXBBR = (Vector3.Dot(right, v3BackBottomRight - center));

        var dotYBBL = (Vector3.Dot(up, v3BackBottomLeft - center));
        var dotYBBR = (Vector3.Dot(up, v3BackBottomRight - center));

        var dotZBBL = (Vector3.Dot(forward, v3BackBottomLeft - center));
        var dotZBBR = (Vector3.Dot(forward, v3BackBottomRight - center));

        //Find the longest vector for each axis
        var maxX = Mathf.Max(dotXFTL, dotXFTR, dotXFBL, dotXFBR, dotXBTL, dotXBTR, dotXBBL, dotXBBR);
        //Debug.DrawRay(center, right * maxX, Color.red); //draw the ray that lies on the outter most extent for this axis
        var maxY = Mathf.Max(dotYFTL, dotYFTR, dotYFBL, dotYFBR, dotYBTL, dotYBTR, dotYBBL, dotYBBR);
        //Debug.DrawRay(center, up * maxY, Color.green); //draw the ray that lies on the outter most extent for this axis
        var maxZ = Mathf.Max(dotZFTL, dotZFTR, dotZFBL, dotZFBR, dotZBTL, dotZBTR, dotZBBL, dotZBBR);

        //Debug.DrawRay(center, forward * maxZ, Color.blue); //draw the ray that lies on the outter most extent for this axis

        return(new Vector3(maxX, maxY, maxZ));         //the vectors local to camera which represent the visible bounds for the rotated object(s)
    }
Example #40
0
 public static Vector3 SetLengthOnAxis(this Vector3 v, Vector3 axis, float len)
 {
     axis.Normalize();
     var d = len - Vector3.Dot(v, axis);
     return v + axis * d;
 }
Example #41
0
        static Vector3 IntersectionPoint(Vector3 vNormal, Vector3[] vLine, double distance)
        {
            Vector3 vPoint = new Vector3();
            Vector3 vLineDir = new Vector3();
            double Numerator = 0.0, Denominator = 0.0, dist = 0.0;

            vLineDir = (vLine[1] - vLine[0]);
            vLineDir = vLineDir.Normalized;

            Numerator = - (vNormal.X * vLine[0].X +
                           vNormal.Y * vLine[0].Y +
                           vNormal.Z * vLine[0].Z + distance);

            Denominator = vNormal.Dot(vLineDir);

            if( Denominator == 0.0)
                return vLine[0];

            dist = Numerator / Denominator;

            vPoint.X = (float)(vLine[0].X + (vLineDir.X * dist));
            vPoint.Y = (float)(vLine[0].Y + (vLineDir.Y * dist));
            vPoint.Z = (float)(vLine[0].Z + (vLineDir.Z * dist));

            return vPoint;
        }
 void OnScrollDragging(BaseHandle handle, HandleEventData eventData = default(HandleEventData))
 {
     m_HierarchyUI.listView.scrollOffset -= Vector3.Dot(eventData.deltaPosition, handle.transform.forward) / this.GetViewerScale();
 }
        private static Point3 GetAtmosphereIntersection( Vector3 pt, Vector3 vec, float radius )
        {
            float a0 = pt.Dot( pt ) - ( radius * radius );
            float a1 = vec.Dot( pt );
            float d = ( a1 * a1 ) - a0;
            float root = ( float )Math.Sqrt( d );
            float t0 = -a1 - root;
            float t1 = -a1 + root;
            float closestT = ( t0 < t1 ) ? t0 : t1;

            return ( pt + vec * closestT ).ToPoint3( );
        }
Example #44
0
 private static float PlaneDistance(Vector3 planeCenter, Vector3 planeNormal, Vector3 point)
 {
     return(Vector3.Dot(point - planeCenter, planeNormal));
 }
Example #45
0
        /// <summary>
        /// 2つのベクトルがなす角をかえす
        /// </summary>
        /// <param name="vecA"></param>
        /// <param name="vecB"></param>
        /// <returns></returns>
        public double VecToRad(Vector3 vecA, Vector3 vecB)
        {
            vecA.Normalize();
            vecB.Normalize();

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

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

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

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

            return dir;
        }
    static float AALinePlaneIntersection(int lineAxis, Vector3 lineLoc, Face face)
    {
        lineLoc[lineAxis] = 0;

        return(Vector3.Dot(face.normal, face.vertices[0] - lineLoc) / face.normal[lineAxis]);
    }
Example #47
0
        public void Dot()
        {
            var vector1 = new Vector3(2.0f, 3.0f, 4.0f);
            var vector2 = new Vector3(5.0f, 6.0f, 7.0f);

            var result = vector1.Dot(vector2);

            Assert.AreEqual(2 * 5 + 3 * 6 + 4 * 7, result);
        }
Example #48
0
        /// <summary>
        ///     Method to curve text along a Unity animation curve.
        /// </summary>
        /// <param name="textComponent"></param>
        /// <returns></returns>
        IEnumerator WarpText()
        {
            VertexCurve.preWrapMode  = WrapMode.Clamp;
            VertexCurve.postWrapMode = WrapMode.Clamp;

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

            Vector3[] vertices;
            Matrix4x4 matrix;

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

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

                    continue;
                }

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

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

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


                if (characterCount == 0)
                {
                    continue;
                }

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

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


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

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

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

                    vertices = textInfo.meshInfo[materialIndex].vertices;

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

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

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

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


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

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

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

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

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

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


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

                yield return(null); // new WaitForSeconds(0.025f);
            }
        }
Example #49
0
        public void Update()
        {
            _UpdateApplicationLifecycle();

            // Hide snackbar when currently tracking at least one plane.
            Session.GetTrackables <DetectedPlane>(m_AllPlanes);
            bool showSearchingUI = true;

            for (int i = 0; i < m_AllPlanes.Count; i++)
            {
                if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
                {
                    showSearchingUI = false;
                    break;
                }
            }

            SearchingForPlaneUI.SetActive(showSearchingUI);

            // If the player has not touched the screen, we are done with this update.
            Touch touch;

            if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
            {
                return;
            }

            // Raycast against the location the player touched to search for planes.
            TrackableHit      hit;
            TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
                                              TrackableHitFlags.FeaturePointWithSurfaceNormal;

            if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit) && spawned == false)
            {
                spawned = true;
                // Use hit pose and camera pose to check if hittest is from the
                // back of the plane, if it is, no need to create the anchor.
                if ((hit.Trackable is DetectedPlane) &&
                    Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position,
                                hit.Pose.rotation * Vector3.up) < 0)
                {
                    Debug.Log("Hit at back of the current DetectedPlane");
                }
                else
                {
                    // Instantiate Andy model at the hit pose.
                    var andyObject = Instantiate(AndyAndroidPrefab, hit.Pose.position, hit.Pose.rotation);

                    // Compensate for the hitPose rotation facing away from the raycast (i.e. camera).
                    andyObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);

                    // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
                    // world evolves.
                    var anchor = hit.Trackable.CreateAnchor(hit.Pose);

                    dragonControls.Dragon = andyObject.transform;
                    dragonControls.Dragon.localEulerAngles = new Vector3(0, 360, 0);
                    dragonControls.gameObject.SetActive(true);

                    // Make Andy model a child of the anchor.
                    andyObject.transform.parent = anchor.transform;
                }
            }
        }
Example #50
0
 public bool WithinVisionCone(BaseEntity other)
 {
     return((double)Vector3.Dot(this.eyes.BodyForward(), Vector3Ex.Direction(((Component)other).get_transform().get_position(), ((Component)this).get_transform().get_position())) >= (double)this.visionCone);
 }
        private bool GetRayAtmosphereIntersection( Point3 origin, Vector3 dir, out Point3 intPt )
        {
            intPt = origin;
            float factor = 0.0001f;
            float fRadius = m_OuterSphere.Radius * factor;
            float fSqrRadius = fRadius * fRadius;

            Vector3 originToCentre = new Vector3( origin.X * factor, origin.Y * factor, origin.Z * factor );
            float a0 = originToCentre.SqrLength - fSqrRadius;

            if ( a0 > 0 )
            {
                return false;
            }
            //	1 intersection: The origin of the ray is inside the sphere
            float a1 = dir.Dot( originToCentre );
            float discriminant = ( a1 * a1 ) - a0;
            float t = -a1 + Functions.Sqrt( discriminant );

            intPt = origin + dir * ( t / factor );
            return true;
        }
Example #52
0
        // compact triangles, compute edge error and build reference list

        void Update_mesh(int iteration)
        {
            if (iteration > 0) // compact triangles
            {
                int dst = 0;
                for (int i = 0; i < triangles.Count; i++)
                {
                    if (triangles[i].deleted == 0)
                    {
                        triangles[dst++] = triangles[i];
                    }
                }
            }
            //
            // Init Quadrics by Plane & Edge Errors
            //
            // required at the beginning ( iteration == 0 )
            // recomputing during the simplification is not required,
            // but mostly improves the result for closed meshes
            //
            if (iteration == 0)
            {
                for (int i = 0; i < vertices.Count; i++)
                {
                    Vertex v = vertices[i];
                    v.q         = new SymetricMatrix(0.0);
                    vertices[i] = v;
                }

                for (int i = 0; i < triangles.Count; i++)
                {
                    Triangle  t = triangles[i];
                    Vector3   n = new Vector3();
                    Vector3[] p = new Vector3[3];
                    for (int j = 0; j < 3; j++)
                    {
                        p[j] = vertices[t.v[j]].p;
                    }
                    n = Vector3.Cross(p[1] - p[0], p[2] - p[0]);
                    n.Normalize();
                    t.n = n;
                    for (int j = 0; j < 3; j++)
                    {
                        Vertex v = vertices[t.v[j]];
                        v.q = vertices[t.v[j]].q + new SymetricMatrix(n.X, n.Y, n.Z, -Vector3.Dot(n, p[0]));
                        vertices[t.v[j]] = v;
                    }
                    triangles[i] = t;
                }
                for (int i = 0; i < triangles.Count; i++)
                {
                    // Calc Edge Error
                    Triangle t = triangles[i];
                    Vector3  p = new Vector3();
                    for (int j = 0; j < 3; j++)
                    {
                        t.err[j] = Calculate_error(t.v[j], t.v[(j + 1) % 3], ref p);
                    }
                    t.err[3]     = Math.Min(t.err[0], Math.Min(t.err[1], t.err[2]));
                    triangles[i] = t;
                }
            }

            // Init Reference ID list
            for (int i = 0; i < vertices.Count; i++)
            {
                Vertex v = vertices[i];
                v.tstart    = 0;
                v.tcount    = 0;
                vertices[i] = v;
            }
            for (int i = 0; i < triangles.Count; i++)
            {
                Triangle t = triangles[i];
                for (int j = 0; j < 3; i++)
                {
                    Vertex v = vertices[t.v[j]];
                    v.tcount++;
                    vertices[t.v[j]] = v;
                }
            }
            int tstart = 0;

            for (int i = 0; i < vertices.Count; i++)
            {
                Vertex v = vertices[i];
                v.tstart    = tstart;
                tstart     += v.tcount;
                v.tcount    = 0;
                vertices[i] = v;
            }

            // Write References
            for (int i = 0; i < triangles.Count; i++)
            {
                Triangle t = triangles[i];
                for (int j = 0; j < 3; j++)
                {
                    Vertex v = vertices[t.v[j]];
                    Ref    r = refs[v.tstart + v.tcount];
                    r.tid     = i;
                    r.tvertex = j;
                    refs[v.tstart + v.tcount] = r;
                    v.tcount++;
                    vertices[t.v[j]] = v;
                }
                triangles[i] = t;
            }

            // Identify boundary : vertices[].border=0,1
            if (iteration == 0)
            {
                ListHelper <int> vcount = new ListHelper <int>();
                ListHelper <int> vids   = new ListHelper <int>();

                for (int i = 0; i < vertices.Count; i++)
                {
                    Vertex v = vertices[i];
                    v.border    = 0;
                    vertices[i] = v;
                }

                for (int i = 0; i < vertices.Count; i++)
                {
                    Vertex v = vertices[i];
                    vcount.Clear();
                    vids.Clear();
                    for (int j = 0; j < v.tcount; j++)
                    {
                        int      kb = refs[v.tstart + j].tid;
                        Triangle t  = triangles[kb];
                        for (int k = 0; k < 3; k++)
                        {
                            int ofs = 0, id = t.v[k];
                            while (ofs < vcount.Count)
                            {
                                if (vids[ofs] == id)
                                {
                                    break;
                                }
                                ofs++;
                            }
                            if (ofs == vcount.Count)
                            {
                                vcount.Add(1);
                                vids.Add(id);
                            }
                            else
                            {
                                vcount[ofs]++;
                            }
                        }
                        triangles[kb] = t;
                    }
                    for (int j = 0; j < vcount.Count; j++)
                    {
                        if (vcount[j] == 1)
                        {
                            Vertex vt = vertices[vids[j]];
                            vt.border         = 1;
                            vertices[vids[j]] = vt;
                        }
                    }
                }
            }
        }
Example #53
0
 public static void InersectPlane(ref Vector3 vector, ref Vector3 planeNormal, out Vector3 result)
 {
     result = vector - (planeNormal * vector.Dot(planeNormal));
 }
Example #54
0
 void Update()
 {
     if (Time.time < delay)
     {
         return;
     }
     // if target is exist.
     if (target)
     {
         // rotation facing to the target.
         Quaternion targetlook = Quaternion.LookRotation(target.transform.position - this.transform.position);
         this.transform.rotation = Quaternion.Lerp(this.transform.rotation, targetlook, Time.deltaTime * 3);
         // find a direction from the target
         Vector3 dir       = (target.transform.position - transform.position).normalized;
         float   direction = Vector3.Dot(dir, transform.forward);
         // check if in front direction
         if (direction > 0.9f)
         {
             if (weapon)
             {
                 // shooting!!.
                 weapon.LaunchWeapon(indexWeapon);
             }
         }
         // AI attack the target for a while (3 sec)
         if (Time.time > timeAIattack + 3)
         {
             target = null;
             // AI forget this target and try to looking new target
         }
     }
     else
     {
         for (int t = 0; t < TargetTag.Length; t++)
         {
             // AI find target only in TargetTag list
             if (GameObject.FindGameObjectsWithTag(TargetTag[t]).Length > 0)
             {
                 // find all objects in Tags list.
                 GameObject[] objs     = GameObject.FindGameObjectsWithTag(TargetTag[t]);
                 float        distance = int.MaxValue;
                 for (int i = 0; i < objs.Length; i++)
                 {
                     // find the distance from the target.
                     float dis = Vector3.Distance(objs[i].transform.position, transform.position);
                     // check if in ranged.
                     if (distance > dis)
                     {
                         // Select closer target
                         distance = dis;
                         target   = objs[i];
                         if (weapon)
                         {
                             // random weapons
                             indexWeapon = Random.Range(0, weapon.WeaponLists.Length);
                         }
                         timeAIattack = Time.time;
                     }
                 }
             }
         }
     }
 }
Example #55
0
        public void Calculate_dot_product()
        {
            var firstOperand = new Vector3(1, 5, 6);
            var secondOperand = new Vector3(4, 9, 1);

            var actual = firstOperand.Dot(secondOperand);
            Assert.AreEqual(actual, 55);
        }
Example #56
0
		public void WidenRectByVector( Vector3 vec, Rectangle inRect, Real minHeight, Real maxHeight, ref Rectangle outRect )
		{
			outRect = inRect;

			var p = new Plane();
			switch ( Alignment )
			{
				case Alignment.Align_X_Y:
					p.Redefine( Vector3.UnitZ, new Vector3( 0, 0, vec.z < 0.0f ? minHeight : maxHeight ) );
					break;

				case Alignment.Align_X_Z:
					p.Redefine( Vector3.UnitY, new Vector3( 0, vec.y < 0.0f ? minHeight : maxHeight, 0 ) );
					break;

				case Alignment.Align_Y_Z:
					p.Redefine( Vector3.UnitX, new Vector3( vec.x < 0.0f ? minHeight : maxHeight, 0, 0 ) );
					break;
			}
			var verticalVal = vec.Dot( p.Normal );

			if ( Utility.RealEqual( verticalVal, 0.0f ) )
			{
				return;
			}

			var corners = new Vector3[4];
			var startHeight = verticalVal < 0.0f ? maxHeight : minHeight;
			GetPoint( inRect.Left, inRect.Top, startHeight, ref corners[ 0 ] );
			GetPoint( inRect.Right - 1, inRect.Top, startHeight, ref corners[ 1 ] );
			GetPoint( inRect.Left, inRect.Bottom - 1, startHeight, ref corners[ 2 ] );
			GetPoint( inRect.Right - 1, inRect.Bottom - 1, startHeight, ref corners[ 3 ] );

			for ( int i = 0; i < 4; ++i )
			{
				var ray = new Ray( corners[ i ] + this.mPos, vec );
				var rayHit = ray.Intersects( p );
				if ( rayHit.Hit )
				{
					var pt = ray.GetPoint( rayHit.Distance );
					// convert back to terrain point
					var terrainHitPos = Vector3.Zero;
					GetTerrainPosition( pt, ref terrainHitPos );
					// build rectangle which has rounded down & rounded up values
					// remember right & bottom are exclusive
					var mergeRect = new Rectangle( (long)terrainHitPos.x*( this.mSize - 1 ), (long)terrainHitPos.y*( this.mSize - 1 ),
												   (long)( terrainHitPos.x*(float)( this.mSize - 1 ) + 0.5f ) + 1,
												   (long)( terrainHitPos.y*(float)( this.mSize - 1 ) + 0.5f ) + 1 );
					outRect.Merge( mergeRect );
				}
			}
		}
Example #57
0
    private void UpdateFunction()
    {
        // We copy the actual velocity into a temporary variable that we can manipulate.
        Vector3 velocity = movement.velocity;

        // Update velocity based on input
        velocity = ApplyInputVelocityChange(velocity);

        // Apply gravity and jumping force
        velocity = ApplyGravityAndJumping(velocity);

        // Moving platform support
        Vector3 moveDistance = Vector3.zero;

        if (MoveWithPlatform())
        {
            Vector3 newGlobalPoint = movingPlatform.activePlatform.TransformPoint(movingPlatform.activeLocalPoint);
            moveDistance = (newGlobalPoint - movingPlatform.activeGlobalPoint);
            if (moveDistance != Vector3.zero)
            {
                controller.Move(moveDistance);
            }

            // Support moving platform rotation as well:
            Quaternion newGlobalRotation = movingPlatform.activePlatform.rotation * movingPlatform.activeLocalRotation;
            Quaternion rotationDiff      = newGlobalRotation * Quaternion.Inverse(movingPlatform.activeGlobalRotation);

            float yRotation = rotationDiff.eulerAngles.y;
            if (yRotation != 0)
            {
                // Prevent rotation of the local up vector
                tr.Rotate(0, yRotation, 0);
            }
        }

        // Save lastPosition for velocity calculation.
        Vector3 lastPosition = tr.position;

        // We always want the movement to be framerate independent.  Multiplying by Time.deltaTime does this.
        Vector3 currentMovementOffset = velocity * Time.deltaTime;

        // Find out how much we need to push towards the ground to avoid loosing grouning
        // when walking down a step or over a sharp change in slope.
        float pushDownOffset = Mathf.Max(controller.stepOffset, new Vector3(currentMovementOffset.x, 0, currentMovementOffset.z).magnitude);

        if (grounded)
        {
            currentMovementOffset -= pushDownOffset * Vector3.up;
        }

        // Reset variables that will be set by collision function
        movingPlatform.hitPlatform = null;
        groundNormal = Vector3.zero;

        // Move our character!
        movement.collisionFlags = controller.Move(currentMovementOffset);

        movement.lastHitPoint = movement.hitPoint;
        lastGroundNormal      = groundNormal;

        if (movingPlatform.enabled && movingPlatform.activePlatform != movingPlatform.hitPlatform)
        {
            if (movingPlatform.hitPlatform != null)
            {
                movingPlatform.activePlatform = movingPlatform.hitPlatform;
                movingPlatform.lastMatrix     = movingPlatform.hitPlatform.localToWorldMatrix;
                movingPlatform.newPlatform    = true;
            }
        }

        // Calculate the velocity based on the current and previous position.
        // This means our velocity will only be the amount the character actually moved as a result of collisions.
        Vector3 oldHVelocity = new Vector3(velocity.x, 0, velocity.z);

        movement.velocity = (tr.position - lastPosition) / Time.deltaTime;
        Vector3 newHVelocity = new Vector3(movement.velocity.x, 0, movement.velocity.z);

        // The CharacterController can be moved in unwanted directions when colliding with things.
        // We want to prevent this from influencing the recorded velocity.
        if (oldHVelocity == Vector3.zero)
        {
            movement.velocity = new Vector3(0, movement.velocity.y, 0);
        }
        else
        {
            float projectedNewVelocity = Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrMagnitude;
            movement.velocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + movement.velocity.y * Vector3.up;
        }

        if (movement.velocity.y < velocity.y - 0.001f)
        {
            if (movement.velocity.y < 0)
            {
                // Something is forcing the CharacterController down faster than it should.
                // Ignore this
                movement.velocity.y = velocity.y;
            }
            else
            {
                // The upwards movement of the CharacterController has been blocked.
                // This is treated like a ceiling collision - stop further jumping here.
                jumping.holdingJumpButton = false;
            }
        }

        // We were grounded but just loosed grounding
        if (grounded && !IsGroundedTest())
        {
            grounded = false;

            // Apply inertia from platform
            if (movingPlatform.enabled &&
                (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||
                 movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer))
            {
                movement.frameVelocity = movingPlatform.platformVelocity;
                movement.velocity     += movingPlatform.platformVelocity;
            }

            SendMessage("OnFall", SendMessageOptions.DontRequireReceiver);
            // We pushed the character down to ensure it would stay on the ground if there was any.
            // But there wasn't so now we cancel the downwards offset to make the fall smoother.
            tr.position += pushDownOffset * Vector3.up;
        }
        // We were not grounded but just landed on something
        else if (!grounded && IsGroundedTest())
        {
            grounded        = true;
            jumping.jumping = false;
            SubtractNewPlatformVelocity();

            SendMessage("OnLand", SendMessageOptions.DontRequireReceiver);
        }

        // Moving platforms support
        if (MoveWithPlatform())
        {
            // Use the center of the lower half sphere of the capsule as reference point.
            // This works best when the character is standing on moving tilting platforms.
            movingPlatform.activeGlobalPoint = tr.position + Vector3.up * (controller.center.y - controller.height * 0.5f + controller.radius);
            movingPlatform.activeLocalPoint  = movingPlatform.activePlatform.InverseTransformPoint(movingPlatform.activeGlobalPoint);

            // Support moving platform rotation as well:
            movingPlatform.activeGlobalRotation = tr.rotation;
            movingPlatform.activeLocalRotation  = Quaternion.Inverse(movingPlatform.activePlatform.rotation) * movingPlatform.activeGlobalRotation;
        }
    }
Example #58
0
 public Plane(Vector3 normal, Vector3 point)
 {
     this.Normal = normal;
     this.D = -normal.Dot(point);
 }
        public override bool scatter(Ray rayIn, HitRecord record, ref Color attenuation, ref Ray scattered)
        {
            Vector3 outNormal;

            // reflect 中实际上是点乘  因此第一个参数是否归一化理论不影响
            Vector3 reflected = _M.reflect(rayIn.normalDirection, record.normal);


            //透明的物体当然不会吸收任何光线
            attenuation = Color.white;
            float   ni_no     = 1f;
            Vector3 refracted = Vector3.zero;
            float   cos       = 0;
            //反射比
            float reflect_prob = 0;

            //回忆一下二次公式 最常见的情况 一个光束 和 球 有两个交点
            //假如光线是从介质内向介质外传播,那么法线就要反转一下

            // 点积 a.b < 0 则 ab 是钝角(基本不同方向)
            // 注意一下 record的法线都是外表面的法线
            // 当光线和外表面法线几乎同方向的时候
            // 表示从光线正从球内射出
            if (Vector3.Dot(rayIn.direction, record.normal) > 0)
            {
                // 那么法线就要反转一下
                outNormal = -record.normal;
                ni_no     = ref_idx;//相对空气折射率

                // 斯涅尔定律
                // n1*sinθ1 = n2*sinθ2
                // θ1是入射角  θ2是折射角
                // n1  n2 分别是折射率
                cos = ni_no * Vector3.Dot(rayIn.normalDirection, record.normal);
            }
            else
            {
                outNormal = record.normal;
                ni_no     = 1f / ref_idx;
                cos       = -Vector3.Dot(rayIn.normalDirection, record.normal);
            }
            //如果没发生折射,就用反射
            if (_M.refract(rayIn.direction, outNormal, ni_no, ref refracted))
            {
                reflect_prob = _M.schlick(cos, ref_idx);
            }
            else
            {
                //此时反射比为100%
                // reflect_prob = 1;
                reflect_prob = _M.schlick(cos, ref_idx);
            }


            //因为一条光线只会采样一个点,所以这里就用蒙特卡洛模拟的方法,用概率去决定数值
            if (_M.R() <= reflect_prob)
            {
                scattered = new Ray(record.p, reflected);
            }
            else
            {
                scattered = new Ray(record.p, refracted);
            }
            return(true);
        }
 public static float ProjectVectorOnUnnormalizedVector(Vector3 projectedV, Vector3 projectOnV)
 {
     return(Vector3.Dot(projectedV, projectOnV) / projectOnV.Length);
 }