public void TestAddNumbers() { //Arrange var math = new MathUtility(); //Act var result = math.AddNumbers(0, 0); //Assert Assert.AreEqual(0, result); }
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); }
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(); }
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; } } }
/// <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(); }
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); }
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); }
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))); }
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); }
/// <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); }
/// <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; } }
/// <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); }
/// <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); }
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); }
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()); }
/// <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)); }
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; } }
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); }
/// <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); }
public void setStartIndex(int startIndex) { mStartIndex = startIndex; MathUtility.clamp(ref mStartIndex, 0, getTextureFrameCount() - 1); }
/// <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); }
// /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); }
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); }
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; } }
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); } }
/// <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(); }
/// <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); }
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); }
/// <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); } }
private void constructExporter(ISldWorks iSldWorksApp) { iSwApp = iSldWorksApp; ActiveSWModel = (ModelDoc2)iSwApp.ActiveDoc; swMath = iSwApp.GetMathUtility(); }
public static float SinTheta(ref Vector w) { return(MathUtility.Sqrt(SinTheta2(ref w))); }