Ejemplo n.º 1
0
        public void TestAddNumbers()    
        {
            //Arrange
            var math = new MathUtility();

            //Act

            var result = math.AddNumbers(0, 0);
            //Assert

            Assert.AreEqual(0, result);
        }
Ejemplo n.º 2
0
        public void TestNegative()
        {
            //Arrange
            var math = new MathUtility();

            //Act

            var result = math.AddNumbers(int.MaxValue, int.MinValue);//becos we did multiplication in math utility
            //Assert

            Assert.AreEqual(int.MaxValue, result);
        }
Ejemplo n.º 3
0
        public void TestAddOneAndOne()
        {
            //Arrange
            var math = new MathUtility();

            //Act

            var result = math.AddNumbers(1, 1);//becos we did multiplication in math utility
            //Assert

            Assert.AreEqual(2, result);
        }
        public AssemblyContext(string assemblyPath)
        {
            //var sw = Activator.GetObject(Type.GetTypeFromProgID("SldWorks.Application")) as SldWorks;
            //var sw = (SldWorks)System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application");
            sw = new SldWorks();
            sw.Visible = true;
            workingFolder = Path.GetDirectoryName(assemblyPath);
            sw.SetCurrentWorkingDirectory(workingFolder);

            var filePath = assemblyPath;

            doc = sw.OpenDoc6(filePath,
                (int)swDocumentTypes_e.swDocASSEMBLY,
                (int)swOpenDocOptions_e.swOpenDocOptions_Silent, "",
                ref error, ref warning);

            drag = (DragOperator)((AssemblyDoc)doc).GetDragOperator();
            math = (MathUtility)sw.GetMathUtility();
        }
Ejemplo n.º 5
0
        public ScreenSpacePolyLine(BezierPath bezierPath, Transform transform, float maxAngleError, float minVertexDst, float accuracy = 1)
        {
            this.transform    = transform;
            transformPosition = transform.position;
            transformRotation = transform.rotation;
            transformScale    = transform.localScale;

            // Split path in vertices based on angle error
            verticesWorld          = new List <Vector3>();
            vertexToPathSegmentMap = new List <int>();
            segmentStartIndices    = new int[bezierPath.NumSegments + 1];

            verticesWorld.Add(bezierPath[0]);
            vertexToPathSegmentMap.Add(0);

            var prevPointOnPath          = bezierPath[0];
            var dstSinceLastVertex       = 0f;
            var lastAddedPoint           = prevPointOnPath;
            var dstSinceLastIntermediary = 0f;

            for (int segmentIndex = 0; segmentIndex < bezierPath.NumSegments; segmentIndex++)
            {
                var segmentPoints = bezierPath.GetPointsInSegment(segmentIndex);

                verticesWorld.Add(segmentPoints[0]);
                vertexToPathSegmentMap.Add(segmentIndex);
                segmentStartIndices[segmentIndex] = verticesWorld.Count - 1;

                prevPointOnPath          = segmentPoints[0];
                lastAddedPoint           = prevPointOnPath;
                dstSinceLastVertex       = 0;
                dstSinceLastIntermediary = 0f;

                var estimatedSegmentLength = CubicBezierUtility.EstimateCurveLength(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3]);
                var divisions = Mathf.CeilToInt(estimatedSegmentLength * accuracy * accuracyMultiplier);
                var increment = 1f / divisions;

                for (float t = increment; t <= 1; t += increment)
                {
                    var pointOnPath     = CubicBezierUtility.EvaluateCurve(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3], t);
                    var nextPointOnPath = CubicBezierUtility.EvaluateCurve(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3], t + increment);
                    // angle at current point on path
                    var localAngle = 180 - MathUtility.MinAngle(prevPointOnPath, pointOnPath, nextPointOnPath);
                    // angle between the last added vertex, the current point on the path, and the next point on the path
                    var angleFromPrevVertex = 180 - MathUtility.MinAngle(lastAddedPoint, pointOnPath, nextPointOnPath);
                    var angleError          = Mathf.Max(localAngle, angleFromPrevVertex);

                    if (angleError > maxAngleError && dstSinceLastVertex >= minVertexDst)
                    {
                        dstSinceLastVertex       = 0;
                        dstSinceLastIntermediary = 0;
                        verticesWorld.Add(pointOnPath);
                        vertexToPathSegmentMap.Add(segmentIndex);
                        lastAddedPoint = pointOnPath;
                    }
                    else
                    {
                        if (dstSinceLastIntermediary > intermediaryThreshold)
                        {
                            verticesWorld.Add(pointOnPath);
                            vertexToPathSegmentMap.Add(segmentIndex);
                            dstSinceLastIntermediary = 0;
                        }
                        else
                        {
                            dstSinceLastIntermediary += (pointOnPath - prevPointOnPath).magnitude;
                        }
                        dstSinceLastVertex += (pointOnPath - prevPointOnPath).magnitude;
                    }
                    prevPointOnPath = pointOnPath;
                }
            }

            segmentStartIndices[bezierPath.NumSegments] = verticesWorld.Count;

            // ensure final point gets added (unless path is closed loop)
            if (!bezierPath.IsClosed)
            {
                verticesWorld.Add(bezierPath[bezierPath.NumPoints - 1]);
            }
            else
            {
                verticesWorld.Add(bezierPath[0]);
            }
            // Calculate length
            cumululativeLengthWorld = new float[verticesWorld.Count];

            for (int i = 0; i < verticesWorld.Count; i++)
            {
                verticesWorld[i] = MathUtility.TransformPoint(verticesWorld[i], transform, bezierPath.Space);

                if (i > 0)
                {
                    pathLengthWorld           += (verticesWorld[i - 1] - verticesWorld[i]).magnitude;
                    cumululativeLengthWorld[i] = pathLengthWorld;
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Constructs a new IJointAxis
        /// </summary>
        /// <param name="path">Path to this joint's storage</param>
        /// <param name="current">The joint that this axis is contained in</param>
        public IJointAxis(string path, Joint current)
        {
            this.swApp = RobotInfo.SwApp;
            this.modelDoc = RobotInfo.ModelDoc;
            this.swData = RobotInfo.SwData;
            this.path = path;
            this.owner = current;
            this.robot = RobotInfo.Robot;

            if (EffortLimit == 0)
            {
                this.EffortLimit = 1;
            }

            if (Axis != null)
            {
                CalcAxisVector();
            }
            mathUtil = (MathUtility)swApp.GetMathUtility();
        }
Ejemplo n.º 7
0
        private void HandleHordeCreation()
        {
            if (_producedUnit.Definition.KindOf.Get(ObjectKinds.Horde))
            {
                _currentDoorState = DoorState.OpenForHordePayload;
            }
            else if (_producedUnit.ParentHorde != null)
            {
                var hordeContain = _producedUnit.ParentHorde.FindBehavior <HordeContainBehavior>();
                hordeContain.Register(_producedUnit);

                var count     = _producedUnit.AIUpdate.TargetPoints.Count;
                var direction = _producedUnit.AIUpdate.TargetPoints[count - 1] - _producedUnit.Translation;
                if (count > 1)
                {
                    direction = _producedUnit.AIUpdate.TargetPoints[count - 1] - _producedUnit.AIUpdate.TargetPoints[count - 2];
                }

                var formationOffset = hordeContain.GetFormationOffset(_producedUnit);
                var offset          = Vector3.Transform(formationOffset, Quaternion.CreateFromYawPitchRoll(MathUtility.GetYawFromDirection(direction.Vector2XY()), 0, 0));
                _producedUnit.AIUpdate.AddTargetPoint(_producedUnit.AIUpdate.TargetPoints[count - 1] + offset);
                _producedUnit.AIUpdate.SetTargetDirection(direction);
            }
        }
        /// <summary>
        /// Determines the direction of gravity that should be applied.
        /// </summary>
        /// <param name="position">The position of the character.</param>
        /// <returns>The direction of gravity that should be applied.</returns>
        public override Vector3 DetermineGravityDirection(Vector3 position)
        {
            var direction       = (position - m_Transform.position);
            var influenceFactor = m_Influence.Evaluate(1 - (direction.magnitude / (m_SphereCollider.radius * MathUtility.ColliderRadiusMultiplier(m_SphereCollider)))) * m_InfluenceMultiplier;

            return(direction.normalized * influenceFactor);
        }
Ejemplo n.º 9
0
        private bool FoundTargetWhileScanning(BehaviorUpdateContext context, BitArray <AutoAcquireEnemiesType> autoAcquireEnemiesWhenIdle)
        {
            return(false);

            var attacksBuildings = autoAcquireEnemiesWhenIdle?.Get(AutoAcquireEnemiesType.AttackBuildings) ?? true;
            var scanRange        = _gameObject.CurrentWeapon.Template.AttackRange;

            var restrictedByScanAngle = _moduleData.MinIdleScanAngle != 0 && _moduleData.MaxIdleScanAngle != 0;
            var scanAngleOffset       = context.GameContext.Random.NextDouble() *
                                        (_moduleData.MaxIdleScanAngle - _moduleData.MinIdleScanAngle) +
                                        _moduleData.MinIdleScanAngle;

            var nearbyObjects = context.GameContext.Scene3D.Quadtree.FindNearby(_gameObject, _gameObject.Transform, scanRange);

            foreach (var obj in nearbyObjects)
            {
                if (obj.Definition.KindOf.Get(ObjectKinds.Structure) && !attacksBuildings)
                {
                    continue;
                }

                if (restrictedByScanAngle)
                {
                    // TODO: test with GLAVehicleTechnicalChassisOne
                    var deltaTranslation = obj.Translation - _gameObject.Translation;
                    var direction        = deltaTranslation.Vector2XY();
                    var angleToObject    = MathUtility.GetYawFromDirection(direction);
                    var angleDelta       = MathUtility.CalculateAngleDelta(angleToObject, _gameObject.EulerAngles.Z + MathUtility.ToRadians(_moduleData.NaturalTurretAngle));

                    if (angleDelta < -scanAngleOffset || scanAngleOffset < angleDelta)
                    {
                        continue;
                    }
                }

                _gameObject.CurrentWeapon.SetTarget(new WeaponTarget(obj));
                return(true);
            }

            return(false);
        }
Ejemplo n.º 10
0
    bool MakeCorrider(node start, node finish, int xDir, int yDir)
    {
        // MakeCorrider2(start, finish, xDir, yDir, 1);
        float minx = 0;
        float miny = 0;
        float maxx = 0;
        float maxy = 0;

        if (xDir != 0)
        {
            if (start.pos.y < finish.pos.y)
            {
                miny = finish.pos.y + 1;
            }
            else
            {
                miny = start.pos.y + 1;
            }
            if (start.pos.y + (start.sizeY) * tileSize < finish.pos.y + (finish.sizeY) * tileSize)
            {
                maxy = start.pos.y + (start.sizeY - 2) * tileSize;
            }
            else
            {
                maxy = finish.pos.y + (finish.sizeY - 2) * tileSize;
            }

            if (maxy <= miny)
            {
                return(false);
            }
            //Going left
            int yStart = Random.Range((int)miny, (int)maxy);
            yStart = MathUtility.roundUp(yStart, 2);
            if (yStart + tileSize >= maxy || yStart - tileSize <= miny)
            {
                return(false);
            }
            if (xDir == -1)
            {
                float xStart   = finish.pos.x + finish.sizeX * tileSize;
                float distance = (start.pos.x) - xStart;

                finish.roomBuilder.AddDoor(new Vector2(xStart - tileSize, yStart));
                start.roomBuilder.AddDoor(new Vector2(xStart + distance, yStart));
                finish.roomBuilder.AddDoor(new Vector2(xStart - tileSize, yStart + tileSize));
                start.roomBuilder.AddDoor(new Vector2(xStart + distance, yStart + tileSize));

                for (int i = 0; i < distance / tileSize; i++)
                {
                    GameObject pathObj = Instantiate(path, new Vector3(xStart + i * 2, yStart, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / tileSize; i++)
                {
                    GameObject pathObj = Instantiate(path, new Vector3(xStart + i * 2, yStart + tileSize, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / tileSize; i++)
                {
                    GameObject pathObj = Instantiate(wall, new Vector3(xStart + i * 2, yStart - tileSize, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / tileSize; i++)
                {
                    GameObject pathObj = Instantiate(pathBottom, new Vector3(xStart + i * 2, yStart + tileSize * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
            }
            // Going right
            if (xDir == 1)
            {
                float xStart   = start.pos.x + start.sizeX * tileSize;
                float distance = (finish.pos.x) - xStart;

                start.roomBuilder.AddDoor(new Vector2(xStart - tileSize, yStart));
                finish.roomBuilder.AddDoor(new Vector2(xStart + distance, yStart));
                start.roomBuilder.AddDoor(new Vector2(xStart - tileSize, yStart + tileSize));
                finish.roomBuilder.AddDoor(new Vector2(xStart + distance, yStart + tileSize));

                for (int i = 0; i < distance / tileSize; i++)
                {
                    GameObject pathObj = Instantiate(path, new Vector3(xStart + i * 2, yStart, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / tileSize; i++)
                {
                    GameObject pathObj = Instantiate(path, new Vector3(xStart + i * 2, yStart + tileSize, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / tileSize; i++)
                {
                    GameObject pathObj = Instantiate(wall, new Vector3(xStart + i * 2, yStart - tileSize, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / tileSize; i++)
                {
                    GameObject pathObj = Instantiate(pathBottom, new Vector3(xStart + i * 2, yStart + 2 * tileSize, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
            }
        }
        if (yDir != 0)
        {
            if (start.pos.x < finish.pos.x)
            {
                minx = finish.pos.x + 1;
            }
            else
            {
                minx = start.pos.x + 1;
            }
            if (start.pos.x + (start.sizeX - 2) * tileSize < finish.pos.x + (finish.sizeX - 2) * tileSize)
            {
                maxx = start.pos.x + (start.sizeX - 2) * tileSize;
            }
            else
            {
                maxx = finish.pos.x + (finish.sizeX - 2) * tileSize;
            }
            if (maxx <= minx)
            {
                return(false);
            }
            int xStart = Random.Range((int)minx, (int)maxx);
            xStart = MathUtility.roundUp(xStart, tileSize);

            if (xStart + tileSize >= maxx || xStart - tileSize <= minx)
            {
                return(false);
            }
            //Debug.Log (minx + " minx " + maxx + " maxx " + yDir + " dir " + xStart);
            if (yDir == -1)
            {
                float yStart   = finish.pos.y + finish.sizeY * tileSize;
                float distance = (start.pos.y) - yStart;

                finish.roomBuilder.AddDoor(new Vector2(xStart, yStart - tileSize));
                start.roomBuilder.AddDoor(new Vector2(xStart, yStart + distance));
                finish.roomBuilder.AddDoor(new Vector2(xStart + tileSize, yStart - tileSize));
                start.roomBuilder.AddDoor(new Vector2(xStart + tileSize, yStart + distance));
                for (int i = 0; i < distance / 2; i++)
                {
                    GameObject pathObj = Instantiate(path, new Vector3(xStart + tileSize, yStart + i * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / 2; i++)
                {
                    GameObject pathObj = Instantiate(path, new Vector3(xStart, yStart + i * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / 2; i++)
                {
                    GameObject pathObj = Instantiate(wall, new Vector3(xStart + tileSize * 2, yStart + i * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / 2; i++)
                {
                    GameObject pathObj = Instantiate(wall, new Vector3(xStart - tileSize, yStart + i * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
            }
            if (yDir == 1)
            {
                float yStart   = start.pos.y + start.sizeY * tileSize;
                float distance = (finish.pos.y) - yStart;

                start.roomBuilder.AddDoor(new Vector2(xStart, yStart - tileSize));
                finish.roomBuilder.AddDoor(new Vector2(xStart, yStart + distance));
                start.roomBuilder.AddDoor(new Vector2(xStart + tileSize, yStart - tileSize));
                finish.roomBuilder.AddDoor(new Vector2(xStart + tileSize, yStart + distance));



                for (int i = 0; i < distance / 2; i++)
                {
                    GameObject pathObj = Instantiate(path, new Vector3(xStart + tileSize, yStart + i * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / 2; i++)
                {
                    GameObject pathObj = Instantiate(path, new Vector3(xStart, yStart + i * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / 2; i++)
                {
                    GameObject pathObj = Instantiate(wall, new Vector3(xStart - tileSize, yStart + i * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
                for (int i = 0; i < distance / 2; i++)
                {
                    GameObject pathObj = Instantiate(wall, new Vector3(xStart + tileSize * 2, yStart + i * 2, 0), Quaternion.identity) as GameObject;
                    start.roomBuilder.floorObjs.Add(pathObj);
                    finish.roomBuilder.floorObjs.Add(pathObj);
                }
            }
        }
        return(true);
    }
 static float DistancePointToLine2D(Vector2 point)
 {
     return(MathUtility.DistanceToLine(point, new Vector2(0, 0), new Vector2(0, 2)));
 }
Ejemplo n.º 12
0
        private void AddGlobalRelay()
        {
            CubeGridEntity entity = new CubeGridEntity(new FileInfo(Essentials.PluginPath + "CommRelay.sbc"));

            entity.EntityId               = BaseEntity.GenerateEntityId();
            entity.DisplayName            = "CommRelayGlobal";
            entity.PositionAndOrientation = new MyPositionAndOrientation(MathUtility.GenerateRandomEdgeVector(), Vector3.Forward, Vector3.Up);

            List <string> commands = new List <string>();

            // Give a list of commands
            foreach (ChatHandlerBase chatBase in Essentials.ChatHandlers)
            {
                if (chatBase.GetMultipleCommandText().Length > 0)
                {
                    foreach (string cmd in chatBase.GetMultipleCommandText())
                    {
                        string[] command = cmd.Split(new char[] { ' ' }, 2);
                        if (!commands.Contains(command[0]))
                        {
                            commands.Add(command[0]);
                        }
                    }
                }
                else
                {
                    string[] command = chatBase.GetCommandText().Split(new char[] { ' ' }, 2);
                    if (!commands.Contains(command[0]))
                    {
                        commands.Add(command[0]);
                    }
                }
            }

            string finalText = "";

            foreach (string command in commands)
            {
                if (finalText != "")
                {
                    finalText += "\n";
                }

                finalText += command;
            }

            finalText += "\n/help";

            if (PluginSettings.Instance.ServerName != "")
            {
                finalText += "\n" + "servername:" + PluginSettings.Instance.ServerName;
            }

            foreach (MyObjectBuilder_CubeBlock block in entity.BaseCubeBlocks)
            {
                MyObjectBuilder_Beacon beacon = block as MyObjectBuilder_Beacon;
                if (beacon != null)
                {
                    beacon.CustomName = finalText;
                }
            }

            SectorObjectManager.Instance.AddEntity(entity);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Is the collider overlapping with any other objects?
        /// </summary>
        /// <param name="dismountCollider">The collider to determine if it is overlapping with another object.</param>
        /// <returns>True if the collider is overlapping.</returns>
        private bool DismountColliderOverlap(Collider dismountCollider)
        {
            if (dismountCollider == null)
            {
                return(true);
            }

            int hitCount;

            if (dismountCollider is CapsuleCollider)
            {
                Vector3 startEndCap, endEndCap;
                var     capsuleCollider = dismountCollider as CapsuleCollider;
                MathUtility.CapsuleColliderEndCaps(capsuleCollider, dismountCollider.transform.TransformPoint(capsuleCollider.center), dismountCollider.transform.rotation, out startEndCap, out endEndCap);
                hitCount = Physics.OverlapCapsuleNonAlloc(startEndCap, endEndCap, capsuleCollider.radius * MathUtility.ColliderRadiusMultiplier(capsuleCollider), m_OverlapColliders,
                                                          m_CharacterLayerManager.SolidObjectLayers, QueryTriggerInteraction.Ignore);
            }
            else if (dismountCollider is BoxCollider)
            {
                var boxCollider = dismountCollider as BoxCollider;
                hitCount = Physics.OverlapBoxNonAlloc(dismountCollider.transform.TransformPoint(boxCollider.center), Vector3.Scale(boxCollider.size, boxCollider.transform.lossyScale) / 2,
                                                      m_OverlapColliders, dismountCollider.transform.rotation, m_CharacterLayerManager.SolidObjectLayers, QueryTriggerInteraction.Ignore);
            }
            else     // SphereCollider.
            {
                var sphereCollider = dismountCollider as SphereCollider;
                hitCount = Physics.OverlapSphereNonAlloc(dismountCollider.transform.TransformPoint(sphereCollider.center), sphereCollider.radius * MathUtility.ColliderRadiusMultiplier(sphereCollider),
                                                         m_OverlapColliders, m_CharacterLayerManager.SolidObjectLayers, QueryTriggerInteraction.Ignore);
            }

            // Any overlap occurs anytime there is more one collider intersecting the dismount colliders.
            return(hitCount > 0);
        }
 /// <summary>
 /// 获取视图X在模型空间的表达
 /// </summary>
 /// <param name="view"></param>
 /// <param name="mathUtility"></param>
 /// <returns></returns>
 public static MathVector GetYAxis(this View view, MathUtility mathUtility)
 {
     return(Vector3.UnitY.ToSwMathPoint(mathUtility).MultiplyTransform(view.ModelToViewTransform.Inverse()) as MathVector);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Rotate the object based on the current torque.
        /// </summary>
        /// <param name="position">The current position of the object.</param>
        /// <param name="rotation">The current rotation of the object. Passed by reference so the updated rotation can be set.</param>
        private void Rotate(Vector3 position, ref Quaternion rotation)
        {
            // The object should rotate to the desired direction after it has bounced and the rotation has settled.
            if ((m_BounceMode == BounceMode.None || m_Bounced) && (m_Torque.sqrMagnitude < m_SettleThreshold || m_MovementSettled))
            {
                if (m_Collider is CapsuleCollider || m_Collider is BoxCollider)
                {
                    if (!m_RotationSettled)
                    {
                        var up     = -m_NormalizedGravity;
                        var normal = up;
                        if (SingleCast(position, rotation, m_NormalizedGravity * c_ColliderSpacing))
                        {
                            normal = m_RaycastHit.normal;
                        }
                        var dot = Mathf.Abs(Vector3.Dot(normal, rotation * Vector3.up));
                        if (dot > 0.0001 && dot < 0.9999)
                        {
                            // Allow the object to be force rotated to a rotation based on the sideways settle threshold. This works well with bullet
                            // shells to allow them to settle upright instead of always settling on their side.
                            var localRotation = MathUtility.InverseTransformQuaternion(Quaternion.LookRotation(Vector3.forward, up), rotation).eulerAngles;
                            if (!m_DeterminedRotation)
                            {
                                m_SettleSideways     = dot < m_SidewaysSettleThreshold;
                                m_DeterminedRotation = true;
                            }
                            localRotation.x = 0;
                            if (m_SettleSideways)   // The collider should settle on its side.
                            {
                                localRotation.z = Mathf.Abs(MathUtility.ClampInnerAngle(localRotation.z)) < 90 ? 0 : 180;
                            }
                            else     // The collider should settle upright.
                            {
                                localRotation.z = MathUtility.ClampInnerAngle(localRotation.z) < 0 ? 270 : 90;
                            }
                            var target    = MathUtility.TransformQuaternion(Quaternion.LookRotation(Vector3.forward, up), Quaternion.Euler(localRotation));
                            var deltaTime = m_TimeScale * Time.fixedDeltaTime * Time.timeScale;
                            rotation = Quaternion.Slerp(rotation, target, m_RotationSpeed * deltaTime);
                        }
                        else
                        {
                            // The object has finished rotating.
                            m_Torque          = Vector3.zero;
                            m_RotationSettled = true;
                        }
                    }
                }
                else
                {
                    m_Torque          = Vector3.zero;
                    m_RotationSettled = true;
                }
            }

            // Determine the new rotation.
            if (m_RotateInMoveDirection && m_Velocity.sqrMagnitude > 0)
            {
                rotation = Quaternion.LookRotation(m_Velocity.normalized, -m_Gravity);
            }
            m_Torque *= Mathf.Clamp01(1 - m_RotationDamping);
            var targetRotation = rotation * Quaternion.Euler(m_Torque);

            // Do not rotate if the collider would intersect with another object. A SphereCollider does not need this check.
            var hitCount = 0;

            if (m_Collider is CapsuleCollider)
            {
                Vector3 startEndCap, endEndCap;
                var     capsuleCollider = m_Collider as CapsuleCollider;
                MathUtility.CapsuleColliderEndCaps(capsuleCollider, position, targetRotation, out startEndCap, out endEndCap);
                hitCount = Physics.OverlapCapsuleNonAlloc(startEndCap, endEndCap, capsuleCollider.radius * MathUtility.CapsuleColliderHeightMultiplier(capsuleCollider), m_ColliderHit, m_ImpactLayers, QueryTriggerInteraction.Ignore);
            }
            else if (m_Collider is BoxCollider)
            {
                var boxCollider = m_Collider as BoxCollider;
                hitCount = Physics.OverlapBoxNonAlloc(MathUtility.TransformPoint(position, m_Transform.rotation, boxCollider.center), Vector3.Scale(boxCollider.size, boxCollider.transform.lossyScale) / 2, m_ColliderHit, m_Transform.rotation, m_ImpactLayers, QueryTriggerInteraction.Ignore);
            }

            // Apply the rotation if the rotation doesnt intersect any object.
            if (hitCount == 0)
            {
                rotation = targetRotation;
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Move the object based on the current velocity.
        /// </summary>
        /// <param name="position">The current position of the object. Passed by reference so the updated position can be set.</param>
        /// <param name="rotation">The current rotation of the object.</param>
        /// <returns>True if the position was updated or the movement has settled.</returns>
        private bool Move(ref Vector3 position, Quaternion rotation)
        {
            // The object can't move if the movement and rotation has settled.
            if (m_MovementSettled && m_RotationSettled && m_SettleThreshold > 0)
            {
                return(true);
            }

            // Stop moving if the velocity is less than a minimum threshold and the object is on the ground.
            if (m_Velocity.sqrMagnitude < m_SettleThreshold && m_RotationSettled)
            {
                // The object should be on the ground before the object has settled.
                if (SingleCast(position, rotation, m_NormalizedGravity * c_ColliderSpacing))
                {
                    m_MovementSettled = true;
                    return(true);
                }
            }

            var deltaTime = m_TimeScale * Time.fixedDeltaTime * Time.timeScale;

            // The object hasn't settled yet - move based on the velocity.
            m_Velocity += m_Gravity * deltaTime;
            m_Velocity *= Mathf.Clamp01(1 - m_Damping * deltaTime);

            // If the object hits an object then it should either reflect off of that object or stop moving.
            var targetPosition = position + m_Velocity * m_Speed * deltaTime;
            var direction      = targetPosition - position;

            if (SingleCast(position, rotation, direction))
            {
                if (m_RaycastHit.transform.gameObject.layer == LayerManager.MovingPlatform)
                {
                    if (m_RaycastHit.transform != m_Platform)
                    {
                        m_Platform = m_RaycastHit.transform;
                        m_PlatformRelativePosition = m_Platform.InverseTransformPoint(position);
                        m_PrevPlatformRotation     = m_Platform.rotation;
                    }
                }
                else
                {
                    m_Platform = null;
                }

                // If the object has settled but not disabled a collision will occur every frame. Prevent the effects from playing because of this.
                if (!m_InCollision)
                {
                    m_InCollision = true;

                    OnCollision(m_RaycastHit);
                }

                if (m_BounceMode != BounceMode.None)
                {
                    Vector3 velocity;
                    if (m_BounceMode == BounceMode.RandomReflect)
                    {
                        // Add ramdomness to the bounce.
                        // This mode should not be used over the network unless it doesn't matter if the object is synchronized (such as a shell).
                        velocity = Quaternion.AngleAxis(Random.Range(-70, 70), m_RaycastHit.normal) * m_Velocity;
                    }
                    else     // Reflect.
                    {
                        velocity = m_Velocity;
                    }

                    // The bounce strenght is dependent on the physic material.
                    var dynamicFrictionValue = m_Collider != null?Mathf.Clamp01(1 - MathUtility.FrictionValue(m_Collider.material, m_RaycastHit.collider.material, true)) : 0;

                    // Update the velocity to the reflection direction.
                    m_Velocity = Vector3.Reflect(velocity, m_RaycastHit.normal) * dynamicFrictionValue * m_BounceMultiplier;
                    if (m_Velocity.magnitude < m_StartSidewaysVelocityMagnitude)
                    {
                        m_MovementSettled = true;
                    }
                    m_Bounced = true;
                    return(false);
                }
                else
                {
                    m_Velocity        = Vector3.zero;
                    m_Torque          = Vector3.zero;
                    m_MovementSettled = true;
                    enabled           = false;
                    return(true);
                }
            }
            else
            {
                m_Platform    = null;
                m_InCollision = false;
            }
            position = targetPosition;
            return(true);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Retruns true if any objects are overlapping with the Trajectory Object.
        /// </summary>
        /// <param name="position">The position of the cast.</param>
        /// <param name="rotation">The rotation of the cast.</param>
        /// <returns>True if any objects are overlapping with the Trajectory Object.</returns>
        private bool OverlapCast(Vector3 position, Quaternion rotation)
        {
            // No need to do a cast if the originator is null.
            if (m_OriginatorTransform == null)
            {
                return(false);
            }

            int hit = 0;

            if (m_Collider is SphereCollider)
            {
                var sphereCollider = m_Collider as SphereCollider;
                hit = Physics.OverlapSphereNonAlloc(MathUtility.TransformPoint(position, m_Transform.rotation, sphereCollider.center),
                                                    sphereCollider.radius * MathUtility.ColliderRadiusMultiplier(sphereCollider), m_ColliderHit, m_ImpactLayers, QueryTriggerInteraction.Ignore);
            }
            else if (m_Collider is CapsuleCollider)
            {
                var     capsuleCollider = m_Collider as CapsuleCollider;
                Vector3 startEndCap, endEndCap;
                MathUtility.CapsuleColliderEndCaps(capsuleCollider, position, rotation, out startEndCap, out endEndCap);
                hit = Physics.OverlapCapsuleNonAlloc(startEndCap, endEndCap, capsuleCollider.radius * MathUtility.ColliderRadiusMultiplier(capsuleCollider), m_ColliderHit, m_ImpactLayers, QueryTriggerInteraction.Ignore);
            }
            else if (m_Collider is BoxCollider)
            {
                var boxCollider = m_Collider as BoxCollider;
                hit = Physics.OverlapBoxNonAlloc(MathUtility.TransformPoint(position, m_Transform.rotation, boxCollider.center), Vector3.Scale(boxCollider.size, boxCollider.transform.lossyScale) / 2, m_ColliderHit, m_Transform.rotation, m_ImpactLayers, QueryTriggerInteraction.Ignore);
            }

            if (hit > 0)
            {
                // The TrajectoryObject is only in an overlap state if the object is overlapping a non-character or camera collider.
                for (int i = 0; i < hit; ++i)
                {
                    if (!m_ColliderHit[i].transform.IsChildOf(m_OriginatorTransform)
#if FIRST_PERSON_CONTROLLER
                        // The object should not hit any colliders who are a child of the camera.
                        && m_ColliderHit[i].transform.gameObject.GetCachedParentComponent <FirstPersonController.Character.FirstPersonObjects>() == null
#endif
                        )
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 18
0
    protected void processKeyboard(float elapsedTime)
    {
        bool redirection = false;
        bool run         = false;

        mTargetSpeed = 0.0f;
        // 有方向键按下和放开就重新判断目标速度方向
        if (mInputManager.getKeyDown(KeyCode.W) ||
            mInputManager.getKeyDown(KeyCode.A) ||
            mInputManager.getKeyDown(KeyCode.S) ||
            mInputManager.getKeyDown(KeyCode.D))
        {
            redirection  = true;
            mTargetSpeed = 5.0f;
        }
        if (mInputManager.getKeyDown(KeyCode.LeftShift))
        {
            run           = true;
            mTargetSpeed *= 2.0f;
        }
        // 有按键放开时,还有被按下的按键时才会重新判断方向
        if (redirection && (
                mInputManager.getKeyUp(KeyCode.W) ||
                mInputManager.getKeyUp(KeyCode.A) ||
                mInputManager.getKeyUp(KeyCode.S) ||
                mInputManager.getKeyUp(KeyCode.D)))
        {
            redirection = true;
        }
        if (redirection)
        {
            mMoveDir = Vector3.zero;
            if (mInputManager.getKeyDown(KeyCode.W))
            {
                mMoveDir += Vector3.forward;
            }
            if (mInputManager.getKeyDown(KeyCode.S))
            {
                mMoveDir += Vector3.back;
            }
            if (mInputManager.getKeyDown(KeyCode.A))
            {
                mMoveDir += Vector3.left;
            }
            if (mInputManager.getKeyDown(KeyCode.D))
            {
                mMoveDir += Vector3.right;
            }
            mMoveDir = mMoveDir.normalized;
        }
        // 计算当前速度
        // 速度发生改变时,当前速度逐渐向目标速度靠近
        float curSpeed = mCharacter.getSpeed().magnitude;

        smoothTarget(mFixedTime, elapsedTime, mMinDeltaSpeed, mTargetSpeed, ref curSpeed);
        //mCharacter.setCurMoveSpeed(curSpeed);
        onSpeed(curSpeed, run);
        // 如果速度为0,则不再继续判断
        if (MathUtility.isFloatZero(mTargetSpeed))
        {
            return;
        }
        // 方向,所有都是角度制的
        mForwardYaw = mCameraManager.getMainCamera().getRotation().y;
        float dirYaw = 0.0f, pitch = 0.0f;

        MathUtility.getDegreeYawPitchFromDirection(mMoveDir, ref dirYaw, ref pitch);
        mTargetWorldYaw = mForwardYaw + dirYaw;
        MathUtility.adjustAngle360(ref mTargetWorldYaw);
        Vector3 curEuler = mCharacter.getWorldRotation();

        // 差值大于180度,则转换为-180到180之间
        if (Mathf.Abs(mTargetWorldYaw - curEuler.y) >= 180.0f)
        {
            MathUtility.adjustAngle180(ref mTargetWorldYaw);
            MathUtility.adjustAngle180(ref curEuler.y);
            smoothTarget(mFixedTime, elapsedTime, mMinDeltaRotation, mTargetWorldYaw, ref curEuler.y);
            MathUtility.adjustAngle360(ref mTargetWorldYaw);
            MathUtility.adjustAngle360(ref curEuler.y);
        }
        else
        {
            smoothTarget(mFixedTime, elapsedTime, mMinDeltaRotation, mTargetWorldYaw, ref curEuler.y);
        }
        mCharacter.setWorldRotation(curEuler);

        Vector3 worldDir = MathUtility.getDirectionFromDegreeYawPitch(mTargetWorldYaw, 0.0f);

        mCharacter.move(worldDir * curSpeed * elapsedTime * 0.3f, Space.World);
    }
Ejemplo n.º 19
0
        void DrawHandle(int i)
        {
            Vector3 handlePosition = MathUtility.TransformPoint(bezierPath[i], creator.transform, bezierPath.Space);

            float anchorHandleSize  = GetHandleDiameter(globalDisplaySettings.anchorSize * data.bezierHandleScale, bezierPath[i]);
            float controlHandleSize = GetHandleDiameter(globalDisplaySettings.controlSize * data.bezierHandleScale, bezierPath[i]);

            bool  isAnchorPoint     = i % 3 == 0;
            bool  isInteractive     = isAnchorPoint || bezierPath.ControlPointMode != BezierPath.ControlMode.Automatic;
            float handleSize        = (isAnchorPoint) ? anchorHandleSize : controlHandleSize;
            bool  doTransformHandle = i == handleIndexToDisplayAsTransform;

            PathHandle.HandleColours handleColours = (isAnchorPoint) ? splineAnchorColours : splineControlColours;
            if (i == handleIndexToDisplayAsTransform)
            {
                handleColours.defaultColour = (isAnchorPoint) ? globalDisplaySettings.anchorSelected : globalDisplaySettings.controlSelected;
            }
            var cap = capFunctions[(isAnchorPoint) ? globalDisplaySettings.anchorShape : globalDisplaySettings.controlShape];

            PathHandle.HandleInputType handleInputType;
            handlePosition = PathHandle.DrawHandle(handlePosition, bezierPath.Space, isInteractive, handleSize, cap, handleColours, out handleInputType, i);

            if (doTransformHandle)
            {
                // Show normals rotate tool
                if (data.showNormals && Tools.current == Tool.Rotate && isAnchorPoint && bezierPath.Space == PathSpace.xyz)
                {
                    Handles.color = handlesStartCol;

                    int     attachedControlIndex = (i == bezierPath.NumPoints - 1) ? i - 1 : i + 1;
                    Vector3 dir             = (bezierPath[attachedControlIndex] - handlePosition).normalized;
                    float   handleRotOffset = (360 + bezierPath.GlobalNormalsAngle) % 360;
                    anchorAngleHandle.radius = handleSize * 3;
                    anchorAngleHandle.angle  = handleRotOffset + bezierPath.GetAnchorNormalAngle(i / 3);
                    Vector3   handleDirection = Vector3.Cross(dir, Vector3.up);
                    Matrix4x4 handleMatrix    = Matrix4x4.TRS(
                        handlePosition,
                        Quaternion.LookRotation(handleDirection, dir),
                        Vector3.one
                        );

                    using (new Handles.DrawingScope(handleMatrix)) {
                        // draw the handle
                        EditorGUI.BeginChangeCheck();
                        anchorAngleHandle.DrawHandle();
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObject(creator, "Set angle");
                            bezierPath.SetAnchorNormalAngle(i / 3, anchorAngleHandle.angle - handleRotOffset);
                        }
                    }
                }
                else
                {
                    handlePosition = Handles.DoPositionHandle(handlePosition, Quaternion.identity);
                }
            }

            switch (handleInputType)
            {
            case PathHandle.HandleInputType.LMBDrag:
                draggingHandleIndex             = i;
                handleIndexToDisplayAsTransform = -1;
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBRelease:
                draggingHandleIndex             = -1;
                handleIndexToDisplayAsTransform = -1;
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBClick:
                draggingHandleIndex = -1;
                if (Event.current.shift)
                {
                    handleIndexToDisplayAsTransform = -1;     // disable move tool if new point added
                }
                else
                {
                    if (handleIndexToDisplayAsTransform == i)
                    {
                        handleIndexToDisplayAsTransform = -1;     // disable move tool if clicking on point under move tool
                    }
                    else
                    {
                        handleIndexToDisplayAsTransform = i;
                    }
                }
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBPress:
                if (handleIndexToDisplayAsTransform != i)
                {
                    handleIndexToDisplayAsTransform = -1;
                    Repaint();
                }
                break;
            }

            Vector3 localHandlePosition = MathUtility.InverseTransformPoint(handlePosition, creator.transform, bezierPath.Space);

            if (bezierPath[i] != localHandlePosition)
            {
                Undo.RecordObject(creator, "Move point");
                bezierPath.MovePoint(i, localHandlePosition);
            }
        }
 /// <summary>
 /// 获取视图垂直向量在模型空间的表达
 /// </summary>
 /// <param name="view"></param>
 /// <param name="mathUtility"></param>
 /// <returns></returns>
 public static Vector3 GetZAxisVec(this View view, MathUtility mathUtility)
 {
     return(view.GetZAxis(mathUtility).ToVector3());
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Returns the anchor position transformed by the local position.
        /// </summary>
        /// <param name="localPosition">The position that the anchor position should be transformed by.</param>
        /// <returns>The anchor position transformed by the local position.</returns>
        protected Vector3 GetAnchorTransformPoint(Vector3 localPosition)
        {
            var anchorPosition = m_CameraController.Anchor.position;

            return(MathUtility.TransformPoint(anchorPosition, m_CameraController.Anchor.rotation, localPosition));
        }
Ejemplo n.º 22
0
    public void ProcessInputs()
    {
        Event e = Event.current;

        if (e.type == EventType.MouseEnterWindow)
        {
            takeInputControl = true;
        }
        if (e.type == EventType.MouseLeaveWindow)
        {
            takeInputControl = false;
        }
        if (!takeInputControl)
        {
            return;
        }

        Vector2 mousPos = InitMouse(e, GetHashCode(), EditorWindow.GetWindow <SceneView>());


        if (selectedBox != null && selectedBox.nodes != null && selectedBox.nodes.Length == 4)
        {
            if (e.type == EventType.KeyDown && e.keyCode == KeyCode.D)
            {
                Undo.RecordObject(polygonAreaEffector, "Removing Box");
                polygonAreaEffector.boxes.Remove(selectedBox);
                EditorUtility.SetDirty(polygonAreaEffector);
            }

            Handles.color = Color.red;
            DrawArrow(selectedBox.origin, selectedBox.RelativeDirection(mousPos));
            Handles.color = Color.white;
            Vector2[] handlePos = new Vector2[4];
            for (int k = 0; k < 4; k++)
            {
                if (k + 1 < 4)
                {
                    handlePos[k] = MathUtility.MiddlePoint(selectedBox.points[k], selectedBox.points[k + 1]);
                }
                else
                {
                    handlePos[k] = MathUtility.MiddlePoint(selectedBox.points[k], selectedBox.points[0]);
                }
            }
            Handles.color = Color.white;
            if (selectedBox.connectionDirection != Vector2.down && DrawCrossHandle(handlePos[0], 0.4f, e))
            {
                CreateBox(Vector2.up);
                return;
            }
            if (selectedBox.connectionDirection != Vector2.left && DrawCrossHandle(handlePos[1], 0.4f, e))
            {
                CreateBox(Vector2.right);
                return;
            }
            if (selectedBox.connectionDirection != Vector2.up && DrawCrossHandle(handlePos[2], 0.4f, e))
            {
                CreateBox(Vector2.down);
                return;
            }
            if (selectedBox.connectionDirection != Vector2.right && DrawCrossHandle(handlePos[3], 0.4f, e))
            {
                CreateBox(Vector2.left);
                return;
            }
            Handles.color = Color.white;
            int i = 0;
            foreach (Vector2 p in selectedBox.points)
            {
                if (Vector2.Distance(p, mousPos) < 0.2f && e.type == EventType.MouseDown)
                {
                    selectedVertexID = i;
                    return;
                }
                i++;
            }
        }
        if (selectedVertexID != -1 && e.type == EventType.MouseUp)
        {
            selectedVertexID = -1;
        }

        if (e.type == EventType.MouseDown)
        {
            selectedBox = GetSelectedBox(mousPos);
        }

        if (selectedVertexID != -1)
        {
            selectedBox.nodes[selectedVertexID].point = mousPos;
        }
    }
Ejemplo n.º 23
0
 public void UpdatePosition()
 {
     ShipyardBox = MathUtility.CreateOrientedBoundingBox((IMyCubeGrid)YardEntity, Tools.Select(x => x.GetPosition()).ToList(), 2.5);
 }
        // /admin movefrom x y z x y z radius
        public override bool HandleCommand(ulong userId, string[] words)
        {
            if (words.Count() < 2)
            {
                Communication.SendPrivateInformation(userId, GetHelp());
                return(true);
            }

            string sourceName = words[0];
            float  distance   = 50f;

            // TODO Allow quotes so we can do distance?
            bool parse = false;

            if (words.Count() > 2)
            {
                parse = float.TryParse(words[words.Count() - 1], out distance);
            }

            string targetName;

            if (parse)
            {
                targetName = string.Join(" ", words.Skip(1).Take(words.Count() - 2).ToArray());
            }
            else
            {
                targetName = string.Join(" ", words.Skip(1).ToArray());
            }

            Communication.SendPrivateInformation(userId, string.Format("Moving {0} to within {1}m of {2}.  This may take about 20 seconds.", sourceName, distance, targetName));

            Vector3D  position;
            IMyEntity entity = Player.FindControlledEntity(targetName);

            if (entity == null)
            {
                entity = CubeGrids.Find(targetName);
                if (entity == null)
                {
                    Communication.SendPrivateInformation(userId, string.Format("Can not find user or grid with the name: {0}", targetName));
                    return(true);
                }
                position = entity.GetPosition();
            }
            else
            {
                position = entity.GetPosition();
            }

            Vector3D  startPosition = MathUtility.RandomPositionFromPoint((Vector3)position, distance);
            IMyEntity gridToMove    = CubeGrids.Find(sourceName);

            if (gridToMove == null)
            {
                Communication.SendPrivateInformation(userId, string.Format("Unable to find: {0}", sourceName));
                return(true);
            }

            Communication.MoveMessage(0, "normal", startPosition.X, startPosition.Y, startPosition.Z, gridToMove.EntityId);

            //Wrapper.GameAction( ( ) =>
            //{
            //    gridToMove.GetTopMostParent( ).SetPosition( startPosition );
            //    Log.Info( string.Format( "Moving '{0}' from {1} to {2}", gridToMove.DisplayName, gridToMove.GetPosition( ), startPosition ) );
            // MyMultiplayer.ReplicateImmediatelly( MyExternalReplicable.FindByObject( gridToMove.GetTopMostParent() ) );
            //} );

            /*
             *          Thread.Sleep(5000);
             *
             *          Wrapper.GameAction(() =>
             *          {
             *              MyAPIGateway.Entities.RemoveFromClosedEntities(entity);
             *              Log.Info(string.Format("Removing '{0}' for move", entity.DisplayName));
             *          });
             *
             *          Thread.Sleep(10000);
             *
             *          Wrapper.GameAction(() =>
             *          {
             *              gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(startPosition, gridBuilder.PositionAndOrientation.Value.Forward, gridBuilder.PositionAndOrientation.Value.Up);
             *              Log.Info(string.Format("Adding '{0}' for move", gridBuilder.DisplayName));
             *              SectorObjectManager.Instance.AddEntity(new CubeGridEntity(gridBuilder));
             *          });*/

            Communication.SendPrivateInformation(userId, string.Format("Moved {0} to within {1}m of {2}", sourceName, (int)Math.Round(Vector3D.Distance(startPosition, position)), targetName));
            return(true);
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Does the actual rotation and height changes. This method is separate from FixedUpdate so the rotation/height can be determined
        /// during server reconciliation on the network.
        /// </summary>
        public void UpdateRotationHeight()
        {
            m_CharacterLocomotion.EnableColliderCollisionLayer(false);
            // The first end cap may change positions.
            if (m_FirstEndCapTarget.localPosition != m_FirstEndCapLocalPosition)
            {
                m_Transform.position       = m_FirstEndCapTarget.position;
                m_FirstEndCapLocalPosition = m_FirstEndCapTarget.localPosition;
            }

            Vector3 localDirection;

            if (m_RotateCollider)
            {
                if (m_EndCapRotation)
                {
                    // Update the rotation of the CapsuleCollider so it is rotated in the same direction as the end cap targets.
                    var direction = m_SecondEndCapTarget.position - m_FirstEndCapTarget.position;
                    m_Transform.rotation = Quaternion.LookRotation(Vector3.Cross(m_CharacterTransform.forward, direction.normalized), direction.normalized);
                }
                else
                {
                    m_Transform.rotation = m_RotationBone.rotation * Quaternion.Euler(m_RotationBoneOffset);
                }
            }

            if (m_AdjustHeight)
            {
                // After the CapsuleCollider has rotated determine the new height of the CapsuleCollider. This can be done by determining the current
                // end cap locations and then getting the offset from the start end cap offsets.
                Vector3 firstEndCap, secondEndCap;
                MathUtility.CapsuleColliderEndCaps(m_CapsuleCollider, m_Transform.position, m_Transform.rotation, out firstEndCap, out secondEndCap);
                var firstEndCapOffset  = m_Transform.InverseTransformDirection(m_FirstEndCapTarget.position - firstEndCap);
                var secondEndCapOffset = m_Transform.InverseTransformDirection(m_SecondEndCapTarget.position - secondEndCap);
                var offset             = m_SecondEndCapOffset - m_FirstEndCapOffset;
                localDirection = ((secondEndCapOffset - firstEndCapOffset) - offset);

                // Determine if the new height would cause any collisions. If it does not then apply the height changes. A negative height change will never cause any
                // collisions so the OverlapCapsule does not need to be checked. A valid capsule collider height is always greater than 2 times the radius of the collider.
                var heightMultiplier = MathUtility.CapsuleColliderHeightMultiplier(m_CapsuleCollider);
                var targetHeight     = m_CapsuleCollider.height + localDirection.y / heightMultiplier;
                if (targetHeight >= m_CapsuleCollider.radius * 2 && (localDirection.y < 0 || !m_CharacterLocomotion.UsingVerticalCollisionDetection ||
                                                                     Physics.OverlapCapsuleNonAlloc(firstEndCap, secondEndCap + m_CharacterLocomotion.Up * localDirection.y,
                                                                                                    m_CapsuleCollider.radius * MathUtility.ColliderRadiusMultiplier(m_CapsuleCollider), m_OverlapColliders, m_CharacterLayerManager.SolidObjectLayers,
                                                                                                    QueryTriggerInteraction.Ignore) == 0))
                {
                    // Adjust the CapsuleCollider height and center to account for the new offset.
                    m_CapsuleCollider.height = targetHeight;
                    var center = m_CapsuleCollider.center;
                    center.y += localDirection.y / (heightMultiplier * 2);
                    m_CapsuleCollider.center = center;
                }
            }
            else
            {
                if (m_PositionBone != null)
                {
                    m_Transform.position = MathUtility.TransformPoint(m_PositionBone.position, m_Transform.rotation, -m_CapsuleCollider.center);
                }
                if (m_HeightOverride != -1)
                {
                    m_CapsuleCollider.height = m_HeightOverride;
                    var center = m_CapsuleCollider.center;
                    center.y = m_CapsuleCollider.height / 2 + m_CenterOffset.y;
                    m_CapsuleCollider.center = center;
                }
            }
            m_CharacterLocomotion.EnableColliderCollisionLayer(true);
        }
Ejemplo n.º 26
0
 public void setStartIndex(int startIndex)
 {
     mStartIndex = startIndex;
     MathUtility.clamp(ref mStartIndex, 0, getTextureFrameCount() - 1);
 }
Ejemplo n.º 27
0
        /// <summary>
        /// Adjusts the collider's center position to the specified value.
        /// </summary>
        /// <param name="targetOffset">The desired offset value.</param>
        private void AdjustCenterOffset(Vector3 targetOffset)
        {
            var delta = targetOffset - m_CenterOffset;

            m_CapsuleCollider.center += delta;
            m_CapsuleCollider.height += delta.y / 2;

            if (!m_CharacterLocomotion.UsingHorizontalCollisionDetection)
            {
                m_CenterOffset = targetOffset;
                return;
            }

            // Apply the offset if there are no collisions.
            var collisionEnabled = m_CharacterLocomotion.CollisionLayerEnabled;

            m_CharacterLocomotion.EnableColliderCollisionLayer(false);
            Vector3 firstEndCap, secondEndCap;

            MathUtility.CapsuleColliderEndCaps(m_CapsuleCollider, m_Transform.position, m_Transform.rotation, out firstEndCap, out secondEndCap);
            if (Physics.OverlapCapsuleNonAlloc(firstEndCap, secondEndCap, m_CapsuleCollider.radius * MathUtility.ColliderRadiusMultiplier(m_CapsuleCollider),
                                               m_OverlapColliders, m_CharacterLayerManager.SolidObjectLayers, QueryTriggerInteraction.Ignore) > 0)
            {
                m_CapsuleCollider.center -= delta;
                m_CapsuleCollider.height -= delta.y / 2;
                m_ColliderOffsetEvent     = Scheduler.Schedule(Time.fixedDeltaTime, AdjustCenterOffset, targetOffset);
            }
            else
            {
                m_CenterOffset = targetOffset;
            }
            m_CharacterLocomotion.EnableColliderCollisionLayer(collisionEnabled);
        }
Ejemplo n.º 28
0
        // /admin movefrom x y z x y z radius
        public override bool HandleCommand(ulong userId, string[] words)
        {
            if (words.Count() < 2)
            {
                Communication.SendPrivateInformation(userId, GetHelp());
                return(true);
            }

            string sourceName = words[0];
            float  distance   = 50f;

            // TODO Allow quotes so we can do distance?
            bool parse = false;

            if (words.Count() > 2)
            {
                parse = float.TryParse(words[words.Count() - 1], out distance);
            }
            if (distance < 10)
            {
                Communication.SendPrivateInformation(userId, string.Format("Minimum distance is 10m"));
                distance = 10;
            }

            string targetName;

            if (parse)
            {
                targetName = string.Join(" ", words.Skip(1).Take(words.Count() - 2).ToArray());
            }
            else
            {
                targetName = string.Join(" ", words.Skip(1).ToArray());
            }

            IMyEntity entity = Player.FindControlledEntity(targetName);

            if (entity == null)
            {
                entity = CubeGrids.Find(targetName);
                if (entity == null)
                {
                    Communication.SendPrivateInformation(userId, string.Format("Can not find user or grid with the name: {0}", targetName));
                    return(true);
                }
            }

            Vector3D position = entity.GetPosition();

            Communication.SendPrivateInformation(userId, string.Format("Trying to move {0} to within {1}m of {2}.  This may take about 20 seconds.", sourceName, distance, targetName));
            Vector3D startPosition = MathUtility.RandomPositionFromPoint((Vector3)position, distance);

            //make sure we aren't moving the player inside a planet or something
            int             tryCount       = 0;
            BoundingSphereD positionSphere = new BoundingSphereD(startPosition, 5);

            while (MyAPIGateway.Entities.GetIntersectionWithSphere(ref positionSphere) != null)
            {
                startPosition  = MathUtility.RandomPositionFromPoint((Vector3)position, distance);
                positionSphere = new BoundingSphereD(startPosition, 5);

                tryCount++;
                if (tryCount > 20)
                {
                    Communication.SendPrivateInformation(userId, string.Format("Could not find valid location to move player: {0}. Try increasing distance.", sourceName));
                    return(true);
                }
            }

            //it's much better to have the client move the player, so we're doing that
            ulong steamId = PlayerMap.Instance.GetSteamIdFromPlayerName(sourceName);

            //send blank move type to pop the user out of any seat they're in
            Communication.MoveMessage(steamId, " ", startPosition);

            /*
             * if (!Player.Move(sourceName, startPosition))
             *          {
             *                  Communication.SendPrivateInformation(userId, string.Format("Can not move user: {0} (Is user in a cockpit or not in game?)", sourceName));
             *                  return true;
             *          }
             */

            Communication.SendPrivateInformation(userId, string.Format("Moved {0} to within {1}m of {2}", sourceName, (int)Math.Round(Vector3D.Distance(startPosition, position)), targetName));
            return(true);
        }
Ejemplo n.º 29
0
        public override TableDefinition Content(ReportData reportData, Dictionary <string, string> options)
        {
            if (reportData?.CurrentSnapshot == null)
            {
                return(null);
            }

            double?criticalViolation = MeasureUtility.GetSizingMeasure(reportData.CurrentSnapshot, Constants.SizingInformations.ViolationsToCriticalQualityRulesNumber);
            double?numCritPerFile    = MeasureUtility.GetSizingMeasure(reportData.CurrentSnapshot, Constants.SizingInformations.ViolationsToCriticalQualityRulesPerFileNumber);
            double?_numCritPerKloc   = MeasureUtility.GetSizingMeasure(reportData.CurrentSnapshot, Constants.SizingInformations.ViolationsToCriticalQualityRulesPerKLOCNumber);

            double?veryHighCostComplexityViolations = CastComplexityUtility.GetCostComplexityGrade(reportData.CurrentSnapshot, Constants.
                                                                                                   QualityDistribution.DistributionOfDefectsToCriticalDiagnosticBasedMetricsPerCostComplexity.GetHashCode(),
                                                                                                   Constants.DefectsToCriticalDiagnosticBasedMetricsPerCostComplexity.CostComplexityDefects_VeryHigh.GetHashCode());

            double?highCostComplexityViolations = CastComplexityUtility.GetCostComplexityGrade(reportData.CurrentSnapshot,
                                                                                               Constants.QualityDistribution.DistributionOfDefectsToCriticalDiagnosticBasedMetricsPerCostComplexity.GetHashCode(),
                                                                                               Constants.DefectsToCriticalDiagnosticBasedMetricsPerCostComplexity.CostComplexityDefects_High.GetHashCode());

            double?veryHighCostComplexityArtefacts = CastComplexityUtility.GetCostComplexityGrade(reportData.CurrentSnapshot,
                                                                                                  Constants.QualityDistribution.CostComplexityDistribution.GetHashCode(),
                                                                                                  Constants.CostComplexity.CostComplexityArtifacts_VeryHigh.GetHashCode());

            double?highCostComplexityArtefacts = CastComplexityUtility.GetCostComplexityGrade(reportData.CurrentSnapshot,
                                                                                              Constants.QualityDistribution.CostComplexityDistribution.GetHashCode(),
                                                                                              Constants.CostComplexity.CostComplexityArtifacts_High.GetHashCode());


            double?nbComplexityArtefacts          = MathUtility.GetSum(veryHighCostComplexityArtefacts, highCostComplexityArtefacts);
            double?nbComplexityArtefactsViolation = MathUtility.GetSum(veryHighCostComplexityViolations, highCostComplexityViolations);



            const string metricFormat          = "N0";
            const string metricFormatPrecision = "N2";

            string numCritPerFileIfNegative;

            // ReSharper disable once CompareOfFloatsByEqualityOperator -- special case
            if (numCritPerFile == -1)
            {
                numCritPerFileIfNegative = Constants.No_Value;
            }
            else
            {
                numCritPerFileIfNegative = numCritPerFile?.ToString(metricFormatPrecision) ?? Constants.No_Value;
            }

            var rowData = new List <string>()
            {
                Labels.Name
                , Labels.Value

                , Labels.ViolationsCritical
                , criticalViolation?.ToString(metricFormat) ?? Constants.No_Value

                , "  " + Labels.PerFile
                , numCritPerFileIfNegative

                , "  " + Labels.PerkLoC
                , _numCritPerKloc?.ToString(metricFormatPrecision) ?? Constants.No_Value

                , Labels.ComplexObjects
                , nbComplexityArtefacts?.ToString(metricFormat) ?? Constants.No_Value

                , "  " + Labels.WithViolations
                , nbComplexityArtefactsViolation?.ToString(metricFormat) ?? Constants.No_Value
            };

            var resultTable = new TableDefinition
            {
                HasRowHeaders    = true,
                HasColumnHeaders = false,
                NbRows           = 6,
                NbColumns        = 2,
                Data             = rowData
            };

            return(resultTable);
        }
Ejemplo n.º 30
0
        internal void Update(BehaviorUpdateContext context, BitArray <AutoAcquireEnemiesType> autoAcquireEnemiesWhenIdle)
        {
            var deltaTime = (float)context.Time.DeltaTime.TotalSeconds;

            var   target = _gameObject.CurrentWeapon?.CurrentTarget;
            float targetYaw;

            if (_gameObject.ModelConditionFlags.Get(ModelConditionFlag.Moving))
            {
                _turretAIstate = TurretAIStates.Recentering;
                _gameObject.CurrentWeapon?.SetTarget(null);
            }

            switch (_turretAIstate)
            {
            case TurretAIStates.Disabled:
                break;     // TODO: how does it get enabled?

            case TurretAIStates.Idle:
                if (target != null)
                {
                    _turretAIstate = TurretAIStates.Turning;
                    _currentTarget = target;
                }
                else if (context.Time.TotalTime > _waitUntil && (autoAcquireEnemiesWhenIdle?.Get(AutoAcquireEnemiesType.Yes) ?? true))
                {
                    _turretAIstate = TurretAIStates.ScanningForTargets;
                }
                break;

            case TurretAIStates.ScanningForTargets:
                if (target == null)
                {
                    if (!FoundTargetWhileScanning(context, autoAcquireEnemiesWhenIdle))
                    {
                        var scanInterval =
                            context.GameContext.Random.NextDouble() *
                            (_moduleData.MaxIdleScanInterval - _moduleData.MinIdleScanInterval) +
                            _moduleData.MinIdleScanInterval;
                        _waitUntil     = context.Time.TotalTime + TimeSpan.FromMilliseconds(scanInterval);
                        _turretAIstate = TurretAIStates.Idle;
                        break;
                    }
                }

                if (!_moduleData.FiresWhileTurning)
                {
                    _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Attacking, false);
                }

                _turretAIstate = TurretAIStates.Turning;
                break;

            case TurretAIStates.Turning:
                if (target == null)
                {
                    _waitUntil     = context.Time.TotalTime + TimeSpan.FromMilliseconds(_moduleData.RecenterTime);
                    _turretAIstate = TurretAIStates.Recentering;
                    break;
                }

                var directionToTarget = (target.TargetPosition - _gameObject.Translation).Vector2XY();
                targetYaw = MathUtility.GetYawFromDirection(directionToTarget) - _gameObject.Yaw;

                if (Rotate(targetYaw, deltaTime))
                {
                    break;
                }

                if (!_moduleData.FiresWhileTurning)
                {
                    _gameObject.ModelConditionFlags.Set(ModelConditionFlag.Attacking, true);
                }

                _turretAIstate = TurretAIStates.Attacking;
                break;

            case TurretAIStates.Attacking:
                if (target == null)
                {
                    _waitUntil     = context.Time.TotalTime + TimeSpan.FromMilliseconds(_moduleData.RecenterTime);
                    _turretAIstate = TurretAIStates.Recentering;
                }
                else if (target != _currentTarget)
                {
                    _turretAIstate = TurretAIStates.Turning;
                    _currentTarget = target;
                }
                break;

            case TurretAIStates.Recentering:
                if (context.Time.TotalTime > _waitUntil)
                {
                    targetYaw = MathUtility.ToRadians(_moduleData.NaturalTurretAngle);
                    if (!Rotate(targetYaw, deltaTime))
                    {
                        _turretAIstate = TurretAIStates.Idle;
                    }
                }
                break;
            }
        }
Ejemplo n.º 31
0
    public static void ValidateConstructionSite(this BuildTask this_build_task, Builder builder)
    {
        //Find building complex our BuildTask is a part of
        List <BuildTask> build_task_segment = builder.Unit.Program
                                              .GetSegment(this_build_task)
                                              .Where(operation => operation is BuildTask &&
                                                     !((operation as BuildTask).Blueprint.HasComponent <Motile>()))
                                              .Select(operation => operation as BuildTask)
                                              .ToList();

        int build_task_index     = build_task_segment.IndexOf(this_build_task);
        List <BuildTask> complex =
            build_task_segment.GetRange(build_task_index,
                                        build_task_segment.Count - build_task_index);

        //Determine if building complex is blocked
        bool complex_is_blocked = false;

        foreach (BuildTask build_task in complex)
        {
            if (!build_task.IsConstructionSiteClear)
            {
                complex_is_blocked = true;
            }
        }

        if (!complex_is_blocked)
        {
            return;
        }


        Sphere complex_bounding_sphere = MathUtility.GetBoundingSphere(complex
                                                                       .Select(build_task => new Sphere(build_task.ConstructionSite,
                                                                                                        build_task.ConstructionSiteSize)));
        Vector3 complex_center = complex_bounding_sphere.Point;
        float   complex_radius = complex_bounding_sphere.Radius;

        //Get block structure and nearby buildings within those blocks.
        //A "block" is a collection buildings separated by space (i.e. roads)

        List <Graph> blocks = GraphUtility.GetBlocks(
            Scene.Main.World.Buildings
            .Select(building => new UnitData(building)),
            MaxBlockNeighborDistance);

        HashSet <Node> nearby_building_nodes = new HashSet <Node>();

        foreach (Graph block in blocks)
        {
            if (block.Nodes.FirstOrDefault(node =>
                                           node.GetPosition().Distance(complex_center) < complex_radius * 8) != null)
            {
                nearby_building_nodes.UnionWith(block.Nodes);
            }
        }


        //Finds all blocks that would be effected by a candidate construction site.
        //"Effected" here means they would aquire new nodes because we would
        //be building new buildings on that block.

        Dictionary <Vector3, Dictionary <Graph, Dictionary <BuildTask, int> > > blocks_abutted_map =
            new Dictionary <Vector3, Dictionary <Graph, Dictionary <BuildTask, int> > >();

        System.Func <Vector3, Dictionary <Graph, Dictionary <BuildTask, int> > > GetBlocksAbutted =
            delegate(Vector3 candidate_site)
        {
            if (!blocks_abutted_map.ContainsKey(candidate_site))
            {
                Vector3 displacement = candidate_site - complex_center;

                Dictionary <Graph, Dictionary <BuildTask, int> > blocks_abutted =
                    new Dictionary <Graph, Dictionary <BuildTask, int> >();

                foreach (BuildTask build_task in complex)
                {
                    Vector3 new_construction_site = build_task.ConstructionSite + displacement;

                    foreach (Graph block in blocks)
                    {
                        foreach (Node node in block.Nodes)
                        {
                            if (new_construction_site.Distance(node.GetPosition()) <
                                (build_task.ConstructionSiteSize +
                                 node.GetSize() +
                                 BlockMargin))
                            {
                                if (!blocks_abutted.ContainsKey(block))
                                {
                                    blocks_abutted[block] = new Dictionary <BuildTask, int>();
                                }

                                if (!blocks_abutted[block].ContainsKey(build_task))
                                {
                                    blocks_abutted[block][build_task] = 0;
                                }

                                blocks_abutted[block][build_task]++;
                            }
                        }
                    }
                }

                blocks_abutted_map[candidate_site] = blocks_abutted;
            }

            return(blocks_abutted_map[candidate_site]);
        };


        //Estimating the connectivity that would result
        //from a candidate construction site. Assumes candidate would
        //only abut one block, and that that the resultant connectivity
        //would only depend on the buildings that directly abut the block
        //(Ignoring new buildings that abut the abutting buildings)

        Dictionary <Vector3, float> resultant_connectivity_map = new Dictionary <Vector3, float>();

        System.Func <Vector3, float> EstimateResultantConnectivity = delegate(Vector3 candidate_site)
        {
            if (!resultant_connectivity_map.ContainsKey(candidate_site))
            {
                Dictionary <Graph, Dictionary <BuildTask, int> > blocks_abutted =
                    GetBlocksAbutted(candidate_site);

                //We assume blocks abutted count > 0, because otherwise, we shouldn't
                //be collided in the first place, right? If this assumption does not
                //hold, we need some sort of special handling because such a
                //candidate will not have a connectivity metric.
                Debug.Assert(blocks_abutted.Keys.Count() > 0,
                             "candidate site does not abut any existing blocks");

                Graph abutting_block = blocks_abutted.Keys.First();

                int new_edges = 0;
                int new_nodes = 0;

                foreach (BuildTask build_task in blocks_abutted[abutting_block].Keys)
                {
                    new_nodes++;

                    new_edges += abutting_block.Nodes
                                 .Where(node => node.GetPosition().Distance(candidate_site) <
                                        (MaxBlockNeighborDistance +
                                         node.GetSize() +
                                         complex_radius)).Count() * 2;
                }

                resultant_connectivity_map[candidate_site] =
                    (abutting_block.Connectivity * abutting_block.Nodes.Count() + new_edges) /
                    (abutting_block.Nodes.Count() + new_nodes);
            }

            return(resultant_connectivity_map[candidate_site]);
        };


        //Culls candidate construction sites based on a set of criteria,
        //such as collisions with existing features and topological
        //concerns with regards to transport.

        System.Func <Vector3, bool> IsCandidateSiteValid = delegate(Vector3 candidate_site)
        {
            //Not within terrain boundaries
            Terrain terrain       = Scene.Main.World.Asteroid.Terrain;
            Vector2 normalized_xz = (candidate_site.XZ() - terrain.GetPosition().XZ()) /
                                    terrain.terrainData.size.XZ();
            if (normalized_xz.x < 0 || normalized_xz.x > 1 ||
                normalized_xz.y < 0 || normalized_xz.y > 1)
            {
                return(false);
            }


            //Too steep
            float slope_in_degrees = terrain.terrainData
                                     .GetSteepness(normalized_xz.x, normalized_xz.y);
            if (slope_in_degrees != 0)
            {
                if (slope_in_degrees > 20)
                {
                    return(false);
                }
            }


            //Must be on the frontier of the abutting block.
            //This is to prevent winding and branching
            Sphere block_bounding_sphere = GetBlocksAbutted(candidate_site).Keys.First()
                                           .GetBoundingSphere();
            float distance_to_center = candidate_site.Distance(block_bounding_sphere.Point);
            if ((block_bounding_sphere.Radius - distance_to_center) > (complex_radius + 1.2f))
            {
                return(false);
            }


            //Collision with existing buildings
            foreach (Unit unit in Scene.Main.World.Buildings)
            {
                if (unit.Physical.Position.Distance(candidate_site) <
                    (unit.Physical.Size + complex_radius))
                {
                    return(false);
                }
            }


            //Collision with highways
            if (Scene.Main.World.Asteroid.HighwaySystem
                .IsObstructingTraffic(candidate_site, complex_radius))
            {
                return(false);
            }


            //Candidate might connect separate blocks together
            Dictionary <Graph, Dictionary <BuildTask, int> > blocks_abutted =
                GetBlocksAbutted(candidate_site);
            if (blocks_abutted.Keys.Count() > 1)
            {
                return(false);
            }


            //Would this increase connectivity to undesirable levels?
            //(Higher connectivity means lower surface area,
            //thus buildings may not be exposed to traffic)
            float connectivity           = blocks_abutted.Keys.First().Connectivity;
            float resultant_connectivity = EstimateResultantConnectivity(candidate_site);

            if (connectivity >= MaxBlockConnectivity)
            {
                if (resultant_connectivity >= connectivity)
                {
                    return(false);
                }
            }
            else if (resultant_connectivity > MaxBlockConnectivity)
            {
                return(false);
            }


            return(true);
        };


        //Generate candidate construction sites by placing the building
        //complex center such that it "cuddles" two existing buildings
        //that neighbor one another.

        //      #######         #######
        //    #         #     #         #
        //   # Building  #   # Building  #
        //   #     A     #   #     B     #
        //    #         #     #         #
        //      #######         #######
        //          >   #######   <
        //         /  #         #  \ 
        //        /  #  Complex  #  \
        //       /   #           #   \
        //      /     #         #     \
        // Cuddling     #######    Cuddling

        System.Func <List <Vector3> > GenerateCandidateSites_Cuddle = delegate()
        {
            List <Vector3> candidate_sites_ = new List <Vector3>();

            IEnumerable <Edge> edges = new Graph(nearby_building_nodes).Edges;

            foreach (Edge edge in edges)
            {
                Node a      = edge.A,
                          b = edge.B;

                if (b.GetUnit().Physical.Position.Distance(complex_center) <
                    a.GetUnit().Physical.Position.Distance(complex_center))
                {
                    Utility.Swap(ref a, ref b);
                }

                Vector3 displacement  = b.GetUnit().Physical.Position - a.GetUnit().Physical.Position;
                float   space_between = displacement.magnitude - (a.GetSize() + b.GetSize());

                if (complex_radius * 2 > space_between &&
                    blocks.Find(block => block.Nodes.Contains(a)).Nodes.Contains(b))
                {
                    float a_side = complex_radius + b.GetSize(),
                          b_side = complex_radius + a.GetSize();

                    float a_angle = Mathf.Acos((Mathf.Pow(b_side, 2) +
                                                Mathf.Pow(displacement.magnitude, 2) -
                                                Mathf.Pow(a_side, 2)) /
                                               (2 * b_side * displacement.magnitude));

                    Vector3 direction = displacement.YChangedTo(0).normalized;
                    Vector3 perpendicular_direction = direction.Crossed(new Vector3(0, 1, 0));

                    float direction_length = Mathf.Cos(a_angle) * b_side;
                    float perpendicular_direction_length = Mathf.Sin(a_angle) * b_side * 1.01f;
                    float height = Mathf.Lerp(a.GetPosition().y,
                                              b.GetPosition().y,
                                              direction_length / displacement.magnitude);

                    candidate_sites_.Add(a.GetPosition().YChangedTo(height) +
                                         direction * direction_length +
                                         perpendicular_direction * perpendicular_direction_length);

                    candidate_sites_.Add(a.GetPosition().YChangedTo(height) +
                                         direction * direction_length -
                                         perpendicular_direction * perpendicular_direction_length);
                }
            }

            return(candidate_sites_);
        };


        //Generates candidate construction sites by computing the minimum
        //spanning tree of all nearby buildings and then attempts to place
        //complex between two neighboring buildings, as near as possible to the
        //building nearest to the original building complex center.

        System.Func <List <Vector3> > GenerateCandidateSites_Between = delegate()
        {
            List <Vector3> candidate_sites_ = new List <Vector3>();

            Graph mst = GraphUtility.CreateHairball(nearby_building_nodes.Select(node =>
                                                                                 new UnitData(node.GetUnit())))
                        .MinimumSpanned_Euclidean();

            foreach (Edge edge in mst.Edges)
            {
                Node a      = edge.A,
                          b = edge.B;

                if (b.GetUnit().Physical.Position.Distance(complex_center) <
                    a.GetUnit().Physical.Position.Distance(complex_center))
                {
                    Utility.Swap(ref a, ref b);
                }

                Vector3 displacement  = b.GetUnit().Physical.Position - a.GetUnit().Physical.Position;
                float   space_between = displacement.magnitude - (a.GetSize() + b.GetSize());

                if (complex_radius * 2 <= space_between &&
                    blocks.Find(block => block.Nodes.Contains(a)).Nodes.Contains(b))
                {
                    candidate_sites_.Add(complex_center +
                                         displacement.normalized *
                                         (a.GetSize() + complex_radius) *
                                         1.01f);
                }
            }

            return(candidate_sites_);
        };


        //Generates candidate construction sites by finding nearest building to
        //the original building complex center and then placing complex next to
        //that building in n equally spaced radial directions.

        System.Func <List <Vector3> > GenerateCandidateSites_Radial = delegate()
        {
            List <Vector3> candidate_sites_ = new List <Vector3>();

            Unit nearest_building = nearby_building_nodes
                                    .MinElement(node => node.GetPosition().Distance(complex_center))
                                    .GetUnit();

            for (int i = 0; i < 10; i++)
            {
                float angle = (i / 10.0f) * (2 * Mathf.PI);

                candidate_sites_.Add(nearest_building.Physical.Position +
                                     new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) *
                                     (nearest_building.Physical.Size + complex_radius) * 1.01f);
            }

            return(candidate_sites_);
        };


        //Attempt to find valid candidate construction sites using each
        //of the generation functions.

        //  1) Generate candidate sites using next generation function
        //  2) Cull invalid sites
        //  3a) If no sites remain, return to step 1, unless
        //      3b) No generation functions remain. BuildTask is canceled.

        List <Vector3> candidate_sites = null;

        List <System.Func <List <Vector3> > > candidate_site_generators =
            Utility.List(GenerateCandidateSites_Cuddle,
                         GenerateCandidateSites_Radial);

        foreach (System.Func <List <Vector3> > candidate_site_generator in candidate_site_generators)
        {
            candidate_sites = candidate_site_generator();

            foreach (Vector3 candidate_site in new List <Vector3>(candidate_sites))
            {
                if (!IsCandidateSiteValid(candidate_site))
                {
                    candidate_sites.Remove(candidate_site);
                }
            }

            if (candidate_sites.Count > 0)
            {
                break;
            }
        }
        if (candidate_sites.Count == 0)
        {
            builder.Unit.Task = null;
            return;
        }


        //Define metrics with which to judge valid candidate sites.
        //Metrics measure "badness", i.e. worse => higher number

        System.Func <Vector3, float> ConnectivityMetric = delegate(Vector3 candidate_site)
        {
            float connectivity    = EstimateResultantConnectivity(candidate_site);
            int   new_connections = GetBlocksAbutted(candidate_site).Values.First().Values.Sum();

            if (connectivity > MaxBlockConnectivity)
            {
                return(new_connections);
            }

            return(-new_connections);
        };

        System.Func <Vector3, float> TargetDistanceMetric = delegate(Vector3 candidate_site)
        {
            return(candidate_site.Distance(complex_center));
        };

        System.Func <Vector3, float> BuilderDistanceMetric = delegate(Vector3 candidate_site)
        {
            return(candidate_site.Distance(builder.Unit.Physical.Position));
        };

        System.Func <Vector3, float> LengthMetric = delegate(Vector3 candidate_site)
        {
            Graph block_abutted = GetBlocksAbutted(candidate_site).Keys.First();

            return(-block_abutted.Nodes
                   .Max(node => block_abutted.Nodes
                        .Max(other_node => node.GetPosition().Distance(other_node.GetPosition()))));
        };

        System.Func <Vector3, float> SmoothnessMetric = delegate(Vector3 candidate_site)
        {
            Graph block_abutted = GetBlocksAbutted(candidate_site).Keys.First();

            return(-block_abutted.Nodes
                   .Sum(node => node.GetPosition().Distance(candidate_site)) /
                   block_abutted.Nodes.Count());
        };

        List <System.Func <Vector3, float> > metrics = Utility.List(
            ConnectivityMetric,
            TargetDistanceMetric,
            BuilderDistanceMetric,
            LengthMetric,
            SmoothnessMetric);

        Dictionary <System.Func <Vector3, float>, float> metric_weights =
            new Dictionary <System.Func <Vector3, float>, float>();

        metric_weights[ConnectivityMetric]    = 0.0f;
        metric_weights[TargetDistanceMetric]  = 4.0f;
        metric_weights[BuilderDistanceMetric] = 4.0f;
        metric_weights[LengthMetric]          = 3.0f;
        metric_weights[SmoothnessMetric]      = 3.0f;


        //Score candidate construction sites by computing weighted
        //metrics and summing. Then, find minimum scored candidate
        //and update ConstructionSite of BuildTasks in complex

        Dictionary <Vector3, float> scores = new Dictionary <Vector3, float>();

        foreach (Vector3 candidate_site in candidate_sites)
        {
            scores[candidate_site] = 0;

            foreach (System.Func <Vector3, float> metric in metrics)
            {
                if (metric_weights[metric] > 0)
                {
                    scores[candidate_site] += metric(candidate_site) * metric_weights[metric];
                }
            }
        }

        List <Vector3> sorted_candidate_sites =
            candidate_sites.Sorted(candidate_site => scores[candidate_site]);

        Vector3 complex_displacement = sorted_candidate_sites.First() - complex_center;

        foreach (BuildTask build_task in complex)
        {
            build_task.Input.PrimaryVariableName =
                Scene.Main.World.MemorizePosition(build_task.ConstructionSite +
                                                  complex_displacement);
        }
    }
Ejemplo n.º 32
0
 /// <summary>
 /// Creates a new Axial Joint
 /// </summary>
 /// <param name="joint">The joint that this joint is in</param>
 /// <param name="path">The storage path for this joint</param>
 public AxialJoint(Joint joint, string path)
     : base(joint,path)
 {
     this.matUtil = (MathUtility)swApp.GetMathUtility();
 }
Ejemplo n.º 33
0
        /// <summary>
        /// Finds the location of the specified <see cref="PointD"/> relative to the specified
        /// arbitrary polygon, given the specified epsilon for coordinate comparisons.</summary>
        /// <param name="q">
        /// The <see cref="PointD"/> coordinates to locate.</param>
        /// <param name="polygon">
        /// An <see cref="Array"/> containing <see cref="PointD"/> coordinates that are the vertices
        /// of an arbitrary polygon.</param>
        /// <param name="epsilon">
        /// The maximum absolute difference at which two coordinates should be considered equal.
        /// </param>
        /// <returns>
        /// A <see cref="PolygonLocation"/> value that indicates the location of <paramref
        /// name="q"/> relative to the specified <paramref name="polygon"/>.</returns>
        /// <exception cref="ArgumentException">
        /// <paramref name="polygon"/> contains less than three elements.</exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="polygon"/> is a null reference.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="epsilon"/> is equal to or less than zero.</exception>
        /// <remarks>
        /// <b>PointInPolygon</b> is identical with the basic <see cref="PointInPolygon(PointD,
        /// PointD[])"/> overload but calls <see cref="MathUtility.Compare"/> with the specified
        /// <paramref name="epsilon"/> to determine whether <paramref name="q"/> coincides with any
        /// edge or vertex of the specified <paramref name="polygon"/>.</remarks>

        public static PolygonLocation PointInPolygon(PointD q, PointD[] polygon, double epsilon)
        {
            if (polygon == null)
            {
                ThrowHelper.ThrowArgumentNullException("polygon");
            }
            if (polygon.Length < 3)
            {
                ThrowHelper.ThrowArgumentExceptionWithFormat(
                    "polygon.Length", Strings.ArgumentLessValue, 3);
            }

            if (epsilon <= 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(
                    "epsilon", epsilon, Strings.ArgumentNotPositive);
            }

            // number of right & left crossings of edge & ray
            int rightCrossings = 0, leftCrossings = 0;

            // last vertex is starting point for first edge
            int    lastIndex = polygon.Length - 1;
            double x1 = polygon[lastIndex].X - q.X, y1 = polygon[lastIndex].Y - q.Y;
            int    dy1 = MathUtility.Compare(y1, 0, epsilon);

            for (int i = 0; i < polygon.Length; i++)
            {
                double x0 = polygon[i].X - q.X, y0 = polygon[i].Y - q.Y;

                int dx0 = MathUtility.Compare(x0, 0, epsilon);
                int dy0 = MathUtility.Compare(y0, 0, epsilon);

                // check if q matches current vertex
                if (dx0 == 0 && dy0 == 0)
                {
                    return(PolygonLocation.Vertex);
                }

                // check if current edge straddles x-axis
                bool rightStraddle = ((dy0 > 0) != (dy1 > 0));
                bool leftStraddle  = ((dy0 < 0) != (dy1 < 0));

                // determine intersection of edge with x-axis
                if (rightStraddle || leftStraddle)
                {
                    double x  = (x0 * y1 - x1 * y0) / (y1 - y0);
                    int    dx = MathUtility.Compare(x, 0, epsilon);

                    if (rightStraddle && dx > 0)
                    {
                        ++rightCrossings;
                    }
                    if (leftStraddle && dx < 0)
                    {
                        ++leftCrossings;
                    }
                }

                // move starting point for next edge
                x1 = x0; y1 = y0; dy1 = dy0;
            }

            // q is on edge if crossings are of different parity
            if (rightCrossings % 2 != leftCrossings % 2)
            {
                return(PolygonLocation.Edge);
            }

            // q is inside for an odd number of crossings, else outside
            return(rightCrossings % 2 == 1 ?
                   PolygonLocation.Inside : PolygonLocation.Outside);
        }
Ejemplo n.º 34
0
    private IEnumerator RunVisualization(HashSet <MyVector2> points)
    {
        //Step 0. Init the triangles we will return
        HashSet <Triangle2> triangles = new HashSet <Triangle2>();



        //Step 1. Sort the points
        List <MyVector2> sortedPoints = new List <MyVector2>(points);

        //OrderBy is always soring in ascending order - use OrderByDescending to get in the other order
        //sortedPoints = sortedPoints.OrderBy(n => n.x).ToList();

        //If we have colinear points we have to sort in both x and y
        sortedPoints = sortedPoints.OrderBy(n => n.x).ThenBy(n => n.y).ToList();



        //Step 2. Create the first triangle so we can start the algorithm because we need edges to look at
        //and see if they are visible

        //Pick the first two points in the sorted list - These are always a part of the first triangle
        MyVector2 p1 = sortedPoints[0];
        MyVector2 p2 = sortedPoints[1];

        //Remove them
        sortedPoints.RemoveAt(0);
        sortedPoints.RemoveAt(0);

        //The problem is the third point
        //If we have colinear points, then the third point in the sorted list is not always a valid point
        //to form a triangle because then it will be flat
        //So we have to look for a better point
        for (int i = 0; i < sortedPoints.Count; i++)
        {
            //We have found a non-colinear point
            LeftOnRight pointRelation = _Geometry.IsPoint_Left_On_Right_OfVector(p1, p2, sortedPoints[i]);

            if (pointRelation == LeftOnRight.Left || pointRelation == LeftOnRight.Right)
            {
                MyVector2 p3 = sortedPoints[i];

                //Remove this point
                sortedPoints.RemoveAt(i);

                //Build the first triangle
                Triangle2 newTriangle = new Triangle2(p1, p2, p3);

                triangles.Add(newTriangle);

                break;
            }
        }

        ////If we have finished search and not found a triangle, that means that all points
        ////are colinear and we cant form any triangles
        //if (triangles.Count == 0)
        //{
        //    Debug.Log("All points you want to triangulate a co-linear");

        //    return null;
        //}



        //Show the triangulation
        ShowTriangles(triangles);

        yield return(new WaitForSeconds(controller.pauseTime));



        //Step 3. Add the other points one-by-one

        //For each point we add we have to calculate a convex hull of the previous points
        //An optimization is to not use all points in the triangulation
        //to calculate the hull because many of them might be inside of the hull
        //So we will use the previous points on the hull and add the point we added last iteration
        //to generate the new convex hull

        //First we need to init the convex hull
        HashSet <MyVector2> triangulatePoints = new HashSet <MyVector2>();

        foreach (Triangle2 t in triangles)
        {
            triangulatePoints.Add(t.p1);
            triangulatePoints.Add(t.p2);
            triangulatePoints.Add(t.p3);
        }

        //Calculate the first convex hull
        List <MyVector2> pointsOnHull = _ConvexHull.JarvisMarch_2D(triangulatePoints);

        //Add the other points one-by-one
        foreach (MyVector2 pointToAdd in sortedPoints)
        {
            bool couldFormTriangle = false;


            //Show which point we draw triangles to
            controller.SetActivePoint(pointToAdd);


            //Loop through all edges in the convex hull
            for (int j = 0; j < pointsOnHull.Count; j++)
            {
                MyVector2 hull_p1 = pointsOnHull[j];
                MyVector2 hull_p2 = pointsOnHull[MathUtility.ClampListIndex(j + 1, pointsOnHull.Count)];

                //First we have to check if the points are colinear, then we cant form a triangle
                LeftOnRight pointRelation = _Geometry.IsPoint_Left_On_Right_OfVector(hull_p1, hull_p2, pointToAdd);

                if (pointRelation == LeftOnRight.On)
                {
                    continue;
                }

                //If this triangle is clockwise, then we can see the edge
                //so we should create a new triangle with this edge and the point
                if (_Geometry.IsTriangleOrientedClockwise(hull_p1, hull_p2, pointToAdd))
                {
                    triangles.Add(new Triangle2(hull_p1, hull_p2, pointToAdd));

                    couldFormTriangle = true;


                    //Show the triangulation
                    ShowTriangles(triangles);

                    yield return(new WaitForSeconds(controller.pauseTime));
                }
            }

            //Add the point to the list of points on the hull
            //Will re-generate the hull by using these points so dont worry that the
            //list is not valid anymore
            if (couldFormTriangle)
            {
                pointsOnHull.Add(pointToAdd);

                //Find the convex hull of the current triangulation
                //It generates a counter-clockwise convex hull
                pointsOnHull = _ConvexHull.JarvisMarch_2D(new HashSet <MyVector2>(pointsOnHull));
            }
            else
            {
                Debug.Log("This point could not form any triangles " + pointToAdd.x + " " + pointToAdd.y);
            }
        }



        yield return(null);
    }
Ejemplo n.º 35
0
        /// <summary>
        /// Throws the throwable object.
        /// </summary>
        public void ThrowItem()
        {
            // m_InstantiatedThrownObject will be null for remote players on the network.
            if (m_InstantiatedThrownObject != null)
            {
                m_InstantiatedThrownObject.transform.parent = null;
                // The collider was previously disabled. Enable it again when it is thrown.
                var collider = m_InstantiatedThrownObject.GetCachedComponent <Collider>();
                collider.enabled = true;

                // When the item is used the trajectory object should start moving on its own.
                if (m_InstantiatedTrajectoryObject != null)
                {
                    // The throwable item may be on the other side of an object (especially in the case of separate arms for the first person perspective). Perform a linecast
                    // to ensure the throwable item doesn' move through any objects.
                    if (!m_CharacterLocomotion.ActiveMovementType.UseIndependentLook(false) &&
                        Physics.Linecast(m_CharacterLocomotion.LookSource.LookPosition(), m_InstantiatedTrajectoryObject.transform.position, out m_RaycastHit,
                                         m_ImpactLayers, QueryTriggerInteraction.Ignore))
                    {
                        m_InstantiatedTrajectoryObject.transform.position = m_RaycastHit.point;
                    }

                    var trajectoryTransform = m_ThrowableItemPerpectiveProperties.TrajectoryLocation != null ? m_ThrowableItemPerpectiveProperties.TrajectoryLocation : m_CharacterTransform;
                    var lookDirection       = m_LookSource.LookDirection(trajectoryTransform.TransformPoint(m_TrajectoryOffset), false, m_ImpactLayers, true);
#if ULTIMATE_CHARACTER_CONTROLLER_VR
                    if (m_VRThrowableItem != null && m_CharacterLocomotion.FirstPersonPerspective)
                    {
                        m_Velocity = m_VRThrowableItem.GetVelocity();
                    }
#endif
                    var velocity = MathUtility.TransformDirection(m_Velocity, Quaternion.LookRotation(lookDirection, m_CharacterLocomotion.Up));
                    // Prevent the item from being thrown behind the character. This can happen if the character is looking straight up and there is a positive
                    // y velocity. Gravity will cause the thrown object to go in the opposite direction.
                    if (Vector3.Dot(velocity.normalized, m_CharacterTransform.forward) < 0)
                    {
                        velocity = m_CharacterTransform.up * velocity.magnitude;
                    }
                    m_InstantiatedTrajectoryObject.Initialize(velocity + (m_CharacterTransform.forward * m_CharacterLocomotion.LocalVelocity.z), Vector3.zero, m_Character, false);
                }
            }

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null)
            {
                // The object has been thrown. If the ItemAction is local then that object should be spawned on the network.
                // Non-local actions should disable the mesh renderers so the object can take its place. The mesh renderers will be enabled again in a separate call.
                if (m_NetworkInfo.IsLocalPlayer())
                {
                    NetworkObjectPool.NetworkSpawn(m_ThrownObject, m_InstantiatedThrownObject);
                }
                else
                {
                    EnableObjectMeshRenderers(false);
                }
            }
#endif

            if (m_Inventory != null)
            {
                m_Inventory.UseItem(m_ConsumableItemType, 1);
            }
        }
Ejemplo n.º 36
0
 private void constructExporter(ISldWorks iSldWorksApp)
 {
     iSwApp = iSldWorksApp;
     ActiveSWModel = (ModelDoc2)iSwApp.ActiveDoc;
     swMath = iSwApp.GetMathUtility();
 }
Ejemplo n.º 37
0
 public static float SinTheta(ref Vector w)
 {
     return(MathUtility.Sqrt(SinTheta2(ref w)));
 }