private void LateUpdate() { var minDist = CelestialBodyUtils.GetThirdPowerRootSafe((float)_celestialBody.Mass) * 0.8f; DrawVelocity(minDist); DrawCircle(minDist); }
void DrawOrbitInEditorFor(CelestialBody body) { int pointsCount = _simControl.sceneElementsDisplayParameters.orbitPointsCount; if (body.isActiveAndEnabled) { if (!Application.isPlaying && body.attractor != null && body.orbitData.isDirty) { if (body.attractor.mass <= 0) { body.attractor.mass = 1e-007; //to avoid div by zero } body.CalculateNewOrbitData(); } Handles.color = Color.white; var points = body.GetOrbitPointsDouble(pointsCount, false, _simControl.sceneElementsDisplayParameters.maxOrbitDistance); for (int i = 1; i < points.Length; i++) { Handles.DrawLine((Vector3)points[i - 1], (Vector3)points[i]); } if (_simControl.sceneElementsDisplayParameters.drawOrbitsEclipticProjection && points.Length > 0) { var point1 = points[0] - _simControl.eclipticNormal * CelestialBodyUtils.DotProduct(points[0], _simControl.eclipticNormal); var point2 = Vector3d.zero; Handles.color = Color.gray; for (int i = 1; i < points.Length; i++) { point2 = points[i] - _simControl.eclipticNormal * CelestialBodyUtils.DotProduct(points[i], _simControl.eclipticNormal); Handles.DrawLine((Vector3)point1, (Vector3)point2); point1 = point2; } } } }
private void DrawCircle(float radius) { if (radius > MinimalRadius) { _circleLine.enabled = true; _circleLine.startWidth = CircleWidth; _circleLine.endWidth = CircleWidth; Vector3 axysX; Vector3 axysY; if (_celestialBody.AttractorRef != null && _celestialBody.OrbitData.IsValidOrbit) { axysX = (Vector3)_celestialBody.OrbitData.SemiMinorAxisBasis; axysY = (Vector3)_celestialBody.OrbitData.SemiMajorAxisBasis; } else { axysX = _celestialBody.Velocity.sqrMagnitude > 0 ? (Vector3)_celestialBody.Velocity.normalized : (Vector3)_celestialBody.SimControlRef.EclipticUp; axysY = (Vector3)CelestialBodyUtils.CrossProduct(axysX, (Vector3)_celestialBody.SimControlRef.EclipticNormal); } _circleLine.positionCount = CirclePointsCount; for (int i = 0; i < CirclePointsCount; i++) { float angle = i * (2f * Mathf.PI / CirclePointsCount); var pointPosition = transform.position + axysX * Mathf.Sin(angle) * radius + axysY * Mathf.Cos(angle) * radius; _circleLine.SetPosition(i, pointPosition); } } else { _circleLine.enabled = false; } }
/// <summary> /// Draw two crossing lines in scene view /// </summary> static void DrawX(Vector3 pos, float size, Color col, Vector3 normal, Vector3 up) { Handles.color = col; Vector3 right = CelestialBodyUtils.CrossProduct(up, normal).normalized; Handles.DrawLine(pos + up * size, pos - up * size); Handles.DrawLine(pos + right * size, pos - right * size); }
private Vector3 GetVelocityPoint() { if (CelestialBodyRef != null) { var v = (Vector3)CelestialBodyRef.Velocity; var minDist = CelestialBodyUtils.GetThirdPowerRootSafe((float)CelestialBodyRef.Mass); return(v.normalized * (minDist + v.magnitude)); } return(transform.localPosition); }
void DrawInclinationMarkForBody(CelestialBody body, float scale) { var norm = CelestialBodyUtils.CrossProduct((Vector3)body.orbitData.orbitNormal, (Vector3)_simControl.eclipticNormal); Handles.color = Color.white; var p = CelestialBodyUtils.CrossProduct(norm, (Vector3)_simControl.eclipticNormal).normalized; Handles.DrawLine((Vector3)body.orbitFocusPoint, (Vector3)body.orbitFocusPoint + p * 3f * scale); Handles.DrawLine((Vector3)body.orbitFocusPoint, (Vector3)body.orbitFocusPoint + CelestialBodyUtils.RotateVectorByAngle(p, (float)body.orbitData.inclination, -norm.normalized) * 3f * scale); Handles.DrawWireArc((Vector3)body.orbitFocusPoint, -norm, p, (float)(body.orbitData.inclination * Mathd.Rad2Deg), 1f * scale); DrawLabelScaled((Vector3)body.orbitFocusPoint + p * scale, (body.orbitData.inclination * Mathd.Rad2Deg).ToString("0") + "\u00B0", Color.white, 10); }
Vector3 GetWorldRaycastPos(Vector2 screenPos) { var ray = cam.ScreenPointToRay(screenPos); if (isShiftDown) { var normal = new Vector3(-ray.direction.x, 0, -ray.direction.z); var hitPos = CelestialBodyUtils.GetRayPlaneIntersectionPoint(worldPosOnXZPlane, normal, ray.origin, ray.direction); return(new Vector3(worldPosOnXZPlane.x, hitPos.y, worldPosOnXZPlane.z)); } else { return(CelestialBodyUtils.GetRayPlaneIntersectionPoint(Vector3.zero, Vector3.up, ray.origin, ray.direction)); } }
private float GetCurrentScale(float Mass) { switch (ScaleType) { case ScaleFunctionType.SqrPow2: if (Mass < 0) { Mass = 0; } return(Mathf.Sqrt(Mass) * ScaleMultiplier); case ScaleFunctionType.SqrPow3: return(CelestialBodyUtils.GetThirdPowerRootSafe(Mass) * ScaleMultiplier); } return(ScaleMultiplier); }
/// <summary> /// Draw simple arrow in scene window at given world coordinates /// </summary> void DrawArrow(Vector3 from, Vector3 to, Color col, Vector3 normal) { var dir = to - from; float dist = dir.magnitude; var dirNorm = dir / dist; //normalized vector float headSize = dist / 6f; var _colBefore = Handles.color; Handles.color = col; Vector3 sideNormal = CelestialBodyUtils.CrossProduct(dir, normal).normalized; Handles.DrawLine(from, from + dirNorm * (dist - headSize)); Handles.DrawLine(from + dirNorm * (dist - headSize) + sideNormal * headSize / 2f, from + dirNorm * (dist - headSize) - sideNormal * headSize / 2f); Handles.DrawLine(from + dirNorm * (dist - headSize) + sideNormal * headSize / 2f, from + dir); Handles.DrawLine(from + dirNorm * (dist - headSize) - sideNormal * headSize / 2f, from + dir); Handles.color = _colBefore; }
private void OnPointerInput(Vector2 pointerScreenPosition, Vector2 lastPointerPosition, int buttonIndex) { if (_currentTarget != null) { if (_currentTarget.CelestialBodyRef != null) { var ray = Camera.main.ScreenPointToRay(pointerScreenPosition); Vector3 orbitNormal = _currentTarget.CelestialBodyRef.GetVelocityPlaneNormal(); var currentRayPlanarHitPoint = CelestialBodyUtils.GetRayPlaneIntersectionPoint(_currentTarget.transform.position, orbitNormal, ray.origin, ray.direction); if (!float.IsNaN(currentRayPlanarHitPoint.x) && !float.IsInfinity(currentRayPlanarHitPoint.x)) { var lastRay = Camera.main.ScreenPointToRay(lastPointerPosition); var lastRayPlanarHitPoint = CelestialBodyUtils.GetRayPlaneIntersectionPoint(_currentTarget.transform.position, orbitNormal, lastRay.origin, lastRay.direction); if (!float.IsNaN(currentRayPlanarHitPoint.x) && !float.IsInfinity(currentRayPlanarHitPoint.x)) { var delta = currentRayPlanarHitPoint - lastRayPlanarHitPoint; _currentTarget.transform.position += delta; } } } } }
/// <summary> /// Process mouse drag and hover events and draw velocity vectors if enabled /// </summary> void ProcessVelocityArrows() { if (!_simControl.sceneElementsDisplayParameters.drawVelocityVectors) { return; } Vector3d velocity = new Vector3d(); Vector3 hpos = new Vector3(); Vector3 pos = new Vector3(); for (int i = 0; i < _bodies.Length; i++) { if (_bodies[i].isActiveAndEnabled) { velocity = _simControl.sceneElementsDisplayParameters.editGlobalVelocity ? _bodies[i].velocity : _bodies[i].relativeVelocity; pos = (Vector3)(_bodies[i].position + velocity * _simControl.sceneElementsDisplayParameters.velocitiesArrowsScale); Handles.DrawCapFunction capFunc; switch (_simControl.sceneElementsDisplayParameters.velocityHandlerType) { case VelocityHandlerType.Circle: capFunc = Handles.CircleCap; break; case VelocityHandlerType.Sphere: capFunc = Handles.SphereCap; break; case VelocityHandlerType.Dot: capFunc = Handles.DotCap; break; default: continue; } Handles.color = Color.white; hpos = Handles.FreeMoveHandle(pos, Quaternion.identity, _simControl.sceneElementsDisplayParameters.handleScale * HandleUtility.GetHandleSize(pos), Vector3.zero, capFunc); if (pos != hpos) { //===== Project onto orbit plane if (_bodies[i].attractor != null && !_simControl.sceneElementsDisplayParameters.editGlobalVelocity && (_simControl.sceneElementsDisplayParameters.keepOrbitPlaneWhileChangeVelocity || _simControl.keepBodiesOnEclipticPlane)) { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); hpos = CelestialBodyUtils.GetRayPlaneIntersectionPoint((Vector3)_bodies[i].position, (Vector3)_bodies[i].orbitData.orbitNormal, ray.origin, ray.direction); } //===== velocity = (new Vector3d(hpos) - _bodies[i].position) / _simControl.sceneElementsDisplayParameters.velocitiesArrowsScale; Undo.RecordObject(_bodies[i], "Velocity change"); if (_simControl.sceneElementsDisplayParameters.editGlobalVelocity) { _bodies[i].velocity = velocity; } else { _bodies[i].relativeVelocity = velocity; } _bodies[i].orbitData.isDirty = true; if (_simControl.sceneElementsDisplayParameters.selectBodyWhenDraggingVelocity) { Selection.activeGameObject = _bodies[i].gameObject; } } } } ShowAllVelocitiesVectors(); }
void DrawOrbitElementsAndLabels() { var prms = _simControl.sceneElementsDisplayParameters; for (int i = 0; i < _bodies.Length; i++) { if (_bodies[i].isValidOrbit) { if (prms.drawPeriapsisPoint) { //===== Periapsis DrawX((Vector3)_bodies[i].orbitPeriapsisPoint, prms.circlesScale, Color.green, (Vector3)_bodies[i].orbitData.orbitNormal, (Vector3)_bodies[i].orbitData.semiMajorAxisBasis); } if (prms.drawPeriapsisLabel) { DrawLabelScaled((Vector3)_bodies[i].orbitPeriapsisPoint, "P", Color.white, 10f); } if (prms.drawApoapsisPoint || prms.drawApoapsisLabel) { //===== Apoapsis if (!double.IsInfinity(_bodies[i].orbitApoapsisPoint.x) && !double.IsNaN(_bodies[i].orbitApoapsisPoint.x)) { if (prms.drawApoapsisPoint) { DrawX((Vector3)_bodies[i].orbitApoapsisPoint, prms.circlesScale, Color.green, (Vector3)_bodies[i].orbitData.orbitNormal, (Vector3)_bodies[i].orbitData.semiMajorAxisBasis); } if (prms.drawApoapsisLabel) { DrawLabelScaled((Vector3)_bodies[i].orbitApoapsisPoint, "A", Color.white, 10f); } } } if (prms.drawCenterOfMassPoint) { //===== Center of mass Handles.color = Color.white; Handles.DrawWireDisc((Vector3)_bodies[i].centerOfMass, (Vector3)_bodies[i].orbitData.orbitNormal, 1f); } Vector3 asc; if ((prms.drawAscendingNodeLabel || prms.drawAscendingNodeLine || prms.drawAscendingNodePoint) && _bodies[i].GetAscendingNode(out asc)) { //===== Ascending node asc = asc + (Vector3)_bodies[i].attractor.position; if (prms.drawAscendingNodePoint) { DrawX(asc, prms.circlesScale, Color.blue, (Vector3)_bodies[i].orbitData.orbitNormal, (Vector3)_bodies[i].orbitData.semiMajorAxisBasis); } if (prms.drawAscendingNodeLine) { Handles.color = new Color(0.1f, 0.3f, 0.8f, 0.8f); Handles.DrawLine((Vector3)_bodies[i].attractor.position, asc); } if (prms.drawAscendingNodeLabel) { DrawLabelScaled(asc, "ASC", Color.white, 10f); } } Vector3 desc; if ((prms.drawDescendingNodeLabel || prms.drawDescendingNodeLine || prms.drawDescendingNodePoint) && _bodies[i].GetDescendingNode(out desc)) { //===== Descending node desc = desc + (Vector3)_bodies[i].attractor.position; if (prms.drawDescendingNodePoint) { DrawX(desc, prms.circlesScale, Color.blue, (Vector3)_bodies[i].orbitData.orbitNormal, (Vector3)_bodies[i].orbitData.semiMajorAxisBasis); } if (prms.drawDescendingNodeLine) { Handles.color = new Color(0.8f, 0.3f, 0.1f, 0.8f); Handles.DrawLine((Vector3)_bodies[i].attractor.position, desc); } if (prms.drawDescendingNodeLabel) { DrawLabelScaled(desc, "DESC", Color.white, 10f); } } if (prms.drawInclinationLabel) { //===== Inclination DrawInclinationMarkForBody(_bodies[i], prms.normalAxisScale); } if (prms.drawRadiusVector) { //===== Radius vector Handles.color = Color.gray; Handles.DrawLine((Vector3)_bodies[i].attractor.position, (Vector3)_bodies[i].position); } if (prms.drawOrbitsNormal) { //===== Orbit normal Handles.color = new Color(0.16f, 0.92f, 0.88f, 0.8f); Handles.DrawLine((Vector3)_bodies[i].orbitCenterPoint, (Vector3)_bodies[i].orbitCenterPoint + (Vector3)_bodies[i].orbitData.orbitNormal * prms.normalAxisScale * 5f); Handles.DrawWireDisc((Vector3)_bodies[i].orbitCenterPoint, (Vector3)_bodies[i].orbitData.orbitNormal, prms.normalAxisScale * 2f); } if (prms.drawSemiAxis) { //===== SemiMinor axis normal Handles.color = Color.blue; Handles.DrawLine((Vector3)_bodies[i].orbitCenterPoint, (Vector3)_bodies[i].orbitCenterPoint + (Vector3)_bodies[i].orbitData.semiMinorAxisBasis * prms.normalAxisScale * 5f); //===== SemiMajor axis normal Handles.color = Color.red; Handles.DrawLine((Vector3)_bodies[i].orbitCenterPoint, (Vector3)_bodies[i].orbitCenterPoint + (Vector3)_bodies[i].orbitData.semiMajorAxisBasis * prms.normalAxisScale * 5f); } } //if valid orbit if (_simControl.sceneElementsDisplayParameters.drawBodiesEclipticProjection) { Handles.color = Color.yellow; var ProjectionPos = _bodies[i].position - _simControl.eclipticNormal * CelestialBodyUtils.DotProduct(_bodies[i].position, _simControl.eclipticNormal); if ((ProjectionPos - _bodies[i].position).sqrMagnitude > 1e-003d) { Handles.DrawDottedLine((Vector3)_bodies[i].position, (Vector3)ProjectionPos, 2f); Handles.DrawWireDisc((Vector3)ProjectionPos, (Vector3)_simControl.eclipticNormal, _simControl.sceneElementsDisplayParameters.circlesScale); } } } //for _bodies }