private void DrawOrbits() { CelestialObject[] allBodies = FindObjectsOfType <CelestialObject>(); VirtualBody[] allVirtualBodies = new VirtualBody[allBodies.Length]; Vector3[] drawPoints = new Vector3[iterations]; // Update virtual bodies for (int i = 0; i < allBodies.Length; i++) { allVirtualBodies[i] = new VirtualBody(allBodies[i]); } foreach (VirtualBody vBody in allVirtualBodies) { // simulate for (int i = 0; i < iterations; i++) { // updating velocity of selected body vBody.UpdateVelocity(allVirtualBodies, timeStep); // updating position vBody.UpdatePosition(timeStep); drawPoints[i] = vBody.position; } // draw orbit for (int i = 0; i < iterations - 1; i++) { Debug.DrawLine(drawPoints[i], drawPoints[i + 1], vBody.pathColor); } } }
// Reset function for initializing the walking provider. void Reset() { // Attempt to fetch the locomotion system. system = FindObjectOfType <LocomotionSystem>(); // Did not find a locomotion system. if (system == null) { Debug.LogWarning("[" + gameObject.name + "][ScaledWalkingProvider]: Did not find a LocomotionSystem in the scene."); } // Attempt to fetch the rig. Rig = FindObjectOfType <XRRig>(); // Did not find a rig. if (Rig == null) { Debug.LogWarning("[" + gameObject.name + "][ScaledWalkingProvider]: Did not find an XRRig in the scene."); } // Attempt to fetch the Camera. MainCamera = Camera.main; // Did not find the main camera. if (MainCamera == null) { Debug.LogWarning("[" + gameObject.name + "][ScaledWalkingProvider]: Did not find a main Camera in the scene."); } // Attempt to find the virtual body gameobject. if (GameObject.Find("Virtual Body") != null) { // Set the virtual body. VirtualBody = GameObject.Find("Virtual Body").gameObject; } // Did not find the virtual body gameobject. else { // Create a virtual body gameobject. VirtualBody = new GameObject("Virtual Body"); // Notify the developer. Debug.Log("[" + gameObject.name + "][ScaledWalkingProvider]: Added a new GameObject 'Virtual Body' to the scene."); } // If the virtual body exists. if (VirtualBody != null) { // Attempt to fetch the character controller. Character = VirtualBody.GetComponent <CharacterController>(); // Did not find a character controller. if (Character == null) { // Add a character controller. Character = VirtualBody.AddComponent <CharacterController>(); // Notify the developer. Debug.Log("[" + gameObject.name + "][ScaledWalkingProvider]: Added a CharacterController to the 'Virtual Body' gameobject."); } } // Select all controllers by default. Controllers = new List <XRController>(FindObjectsOfType <XRController>()); }
private void UpdateVirtualBodyVelocity(VirtualBody targetBody, VirtualBody[] allBodies) { var targetVelocity = targetBody.velocity; for (int i = 0; i < allBodies.Length; i++) { if (allBodies[i] == targetBody) { continue; } if (_RelativeTo) { if (i == _RelativeBodyIndex) { continue; } } var gravityVector = targetBody.CalculateGravityVector(allBodies[i]); targetVelocity = targetVelocity + (gravityVector / targetBody.mass); } targetBody.velocity = targetVelocity; }
private void DrawOrbit(VirtualBody body) { switch (useRelativeObject) { case RelativeTo.nothing: Debug.DrawLine(body.lastPosition, body.position, body.mainColor); break; case RelativeTo.strongestAcceleration: if (body == relativeObject) { break; } Debug.DrawLine(body.lastPosition - (body.parent.lastPosition - body.parent.initialPosition), body.position - (body.parent.position - body.parent.initialPosition), body.mainColor); break; case RelativeTo.mostMassive: case RelativeTo.selected: if (body == relativeObject) { } Debug.DrawLine(body.lastPosition - (relativeObject.lastPosition - relativeObject.initialPosition), body.position - (relativeObject.position - relativeObject.initialPosition), body.mainColor); break; default: break; } }
void Update() { if (DrawTrajectories) { if (VirtualCelestialBodies == null || VirtualCelestialBodies.Length != _CelestialBodies.Count) { VirtualCelestialBodies = new VirtualBody[_CelestialBodies.Count]; } for (int i = 0; i < VirtualCelestialBodies.Length; i++) { VirtualCelestialBodies[i] = new VirtualBody(_CelestialBodies[i]); } for (int n = 0; n < NumberOfSteps; n++) { for (int i = 0; i < VirtualCelestialBodies.Length; i++) { UpdateVirtualBodyVelocity(VirtualCelestialBodies[i], VirtualCelestialBodies); } for (int i = 0; i < VirtualCelestialBodies.Length; i++) { var previousPosition = VirtualCelestialBodies[i].position; UpdateVirtualBodyPosition(VirtualCelestialBodies[i]); Debug.DrawLine(previousPosition, VirtualCelestialBodies[i].position, VirtualCelestialBodies[i].trajectoryColor); } } } }
void DrawOrbits() { CelestialBody[] bodies = FindObjectsOfType <CelestialBody>(); VirtualBody[] vbodies = new VirtualBody[bodies.Length]; Vector3[][] drawPoints = new Vector3[bodies.Length][]; //init virtual bodies to have positions without touching the actual bodies for (int i = 0; i < vbodies.Length; i++) { vbodies[i] = new VirtualBody(bodies[i]); drawPoints[i] = new Vector3[nbIter]; } //update the virtual positions for nbIter steps for (int i = 0; i < nbIter; i++) { //update velocity for (int j = 0; j < vbodies.Length; j++) { vbodies[j].velocity += CalculateAcceleration(j, vbodies) * UniverseRules.timeStep; } //update position for (int j = 0; j < vbodies.Length; j++) { if (!bodies[j].staticStar) { vbodies[j].position += vbodies[j].velocity * UniverseRules.timeStep; } //save the point to draw drawPoints[j][i] = vbodies[j].position; } } //draw the lines for (int i = 0; i < vbodies.Length; i++) { Color trajectoryColor = bodies[i].starColor; if (thickLines) { LineRenderer lr = bodies[i].GetComponent <LineRenderer>(); lr.enabled = true; lr.positionCount = drawPoints[i].Length; lr.SetPositions(drawPoints[i]); lr.material = bodies[i].GetComponent <MeshRenderer>().sharedMaterial; lr.startColor = trajectoryColor; lr.endColor = trajectoryColor; lr.widthMultiplier = .1f; } else { LineRenderer lr = bodies[i].GetComponent <LineRenderer>(); lr.enabled = false; for (int j = 0; j < drawPoints[i].Length - 1; j++) { Debug.DrawLine(drawPoints[i][j], drawPoints[i][j + 1], trajectoryColor); } } } }
void DrawOrbits(float delta) { var virtualBodies = new VirtualBody[Universe.spaceBodies.Count]; var drawPoints = new Vector3[Universe.spaceBodies.Count][]; int referenceFrameIndex = 0; Vector3 referenceBodyInitialPosition = new Vector3(0, 0, 0); // Initialize virtual bodies (don't want to move the actual bodies) for (int i = 0; i < virtualBodies.Length; i++) { virtualBodies[i] = new VirtualBody(Universe.spaceBodies[i]); drawPoints[i] = new Vector3[numSteps]; if (Universe.spaceBodies[i] == centralBody && relativeToBody) { referenceFrameIndex = i; referenceBodyInitialPosition = virtualBodies[i].position; } } // Simulate for (int step = 0; step < numSteps; step++) { Vector3 referenceBodyPosition = (relativeToBody) ? virtualBodies[referenceFrameIndex].position : new Vector3(0, 0, 0); // Update velocities for (int i = 0; i < virtualBodies.Length; i++) { virtualBodies[i].velocity += CalculateAcceleration(i, virtualBodies) * timeStep; } // Update positions for (int i = 0; i < virtualBodies.Length; i++) { Vector3 newPos = virtualBodies[i].position + virtualBodies[i].velocity * timeStep; virtualBodies[i].position = newPos; if (relativeToBody) { var referenceFrameOffset = referenceBodyPosition - referenceBodyInitialPosition; newPos -= referenceFrameOffset; } if (relativeToBody && i == referenceFrameIndex) { newPos = referenceBodyInitialPosition; } drawPoints[i][step] = newPos; } } // Draw paths for (int bodyIndex = 0; bodyIndex < virtualBodies.Length; bodyIndex++) { var pathColour = new Color(1, 0, 0); //Universe.spaceBodies[bodyIndex].gameObject.GetComponentInChildren<MeshRenderer> ().sharedMaterial.color; // for (int i = 0; i < drawPoints[bodyIndex].Length - 1; i++) { linedrawer.drawLine(drawPoints[bodyIndex][i], drawPoints[bodyIndex][i + 1], pathColour, delta, false); } } }
private void DrawCollision(VirtualBody body, VirtualBody otherBody) { Gizmos.color = body.mainColor; Gizmos.DrawSphere(body.position, body.radius); //Gizmos.DrawMesh(sphereMesh, body.position, Quaternion.identity, Vector3.one * body.radius); Gizmos.color = otherBody.mainColor; Gizmos.DrawSphere(otherBody.position, otherBody.radius); //Gizmos.DrawMesh(sphereMesh, otherBody.position, Quaternion.identity, Vector3.one * otherBody.radius); }
public Vector3 CalculateGravityVector(VirtualBody targetBody) { Vector3 distanceVector = targetBody.position - position; Vector3 gravityDirection = distanceVector.normalized; float distance = distanceVector.magnitude; float gravity = (Universe.gravitationalConstant * targetBody.mass * mass) / (distance * distance); return(gravityDirection * gravity); }
void DrawOrbits() { GravityBody[] bodies = FindObjectsOfType <GravityBody>(); vrBodies = new VirtualBody[bodies.Length]; Vector3[][] drawPoints = new Vector3[bodies.Length][]; Vector3 referenceBodyInitialPosition = Vector3.zero; int referenceBodyIndex = -1; for (int i = 0; i < bodies.Length; i++) { vrBodies[i] = new VirtualBody(bodies[i]); drawPoints[i] = new Vector3[numSteps]; if (bodies[i] == centralBody && relativeToBody) { referenceBodyIndex = i; referenceBodyInitialPosition = vrBodies[referenceBodyIndex].position; } } // Simulate for (int step = 0; step < numSteps; step++) { Vector3 referenceBodyPosition = relativeToBody ? vrBodies[referenceBodyIndex].position : Vector3.zero; // Update velocities for (int i = 0; i < vrBodies.Length; i++) { vrBodies[i].velocity += CalcAccelerationAt(vrBodies[i].position, vrBodies[i]) * timeStep; } // Update positions for (int i = 0; i < vrBodies.Length; i++) { vrBodies[i].position = vrBodies[i].position + vrBodies[i].velocity * timeStep; var referenceFrameOffset = referenceBodyPosition - referenceBodyInitialPosition; drawPoints[i][step] = i == referenceBodyIndex ? referenceBodyInitialPosition : vrBodies[i].position - referenceFrameOffset; } } // Draw paths for (int i = 0; i < vrBodies.Length; i++) { var pathColour = bodies[i].gameObject.GetComponentInChildren <MeshRenderer>().sharedMaterial.color; var lineRenderer = bodies[i].gameObject.GetComponentInChildren <LineRenderer>(); if (lineRenderer != null) { lineRenderer.enabled = true; lineRenderer.positionCount = numSteps; lineRenderer.SetPositions(drawPoints[i]); lineRenderer.startColor = pathColour; lineRenderer.endColor = pathColour; lineRenderer.useWorldSpace = true; } } }
private void DrawOrbits() { collision = null; CelestialBody[] bodies = FindObjectsOfType <CelestialBody>(); relativeObject = null; VirtualBody[] virtualBodies = new VirtualBody[bodies.Length]; for (int i = 0; i < bodies.Length; i++) { virtualBodies[i] = new VirtualBody(bodies[i]); if (useRelativeObject == RelativeTo.selected && relativeToObject == bodies[i]) { relativeObject = virtualBodies[i]; } if ((useRelativeObject == RelativeTo.mostMassive || useRelativeObject == RelativeTo.strongestAcceleration) && (relativeObject == null || virtualBodies[i].mass > relativeObject.mass)) { relativeObject = virtualBodies[i]; relativeToObject = bodies[i]; } } for (int step = 0; step < steps; step++) { if (collision.HasValue) { break; } foreach (var body in virtualBodies) { bool useStrongest = useRelativeObject == RelativeTo.strongestAcceleration; body.velocity += CalculateAcceleration(body, virtualBodies, 1f) * timeStep; } foreach (var body in virtualBodies) { body.SetNewPosition(body.position + body.velocity * timeStep); } foreach (var body in virtualBodies) { foreach (var otherBody in virtualBodies) { if (body == otherBody) { continue; } float distance = Vector3.Distance(body.position, otherBody.position); if (distance < body.radius + otherBody.radius) { collision = new KeyValuePair <VirtualBody, VirtualBody>(body, otherBody); } } DrawOrbit(body); } } }
private void OnDrawGizmos() { if (precomputation) { var bodies = GameObject.FindObjectsOfType <CelestialBody>(); VirtualBody[] virtualBodies = new VirtualBody[bodies.Length]; for (int i = 0; i < bodies.Length; i++) { virtualBodies[i] = new VirtualBody(bodies[i]); } Vector3[][] bodiesPath = new Vector3[virtualBodies.Length][]; for (int i = 0; i < bodiesPath.Length; i++) { bodiesPath[i] = new Vector3[stepCount + 1]; bodiesPath[i][0] = virtualBodies[i].position; } for (int step = 1; step <= stepCount; step++) { for (int index = 0; index < virtualBodies.Length; index++) { VirtualBody virtualBody = virtualBodies[index]; PreCalculate(virtualBody, virtualBodies, stepTime); } for (int index = 0; index < virtualBodies.Length; index++) { VirtualBody virtualBody = virtualBodies[index]; virtualBody.position += virtualBody.velocity * stepTime; bodiesPath[index][step] = virtualBody.position; } } for (int i = 0; i < bodiesPath.Length; i++) { var path = bodiesPath[i]; if (path.Length > 2) { Gizmos.color = bodies[i].color; for (int j = 0; j < path.Length - 1; j++) { Gizmos.DrawLine(path[j], path[j + 1]); } } } } }
/// <summary> /// 预计算 /// </summary> private void PreCalculate(VirtualBody body, VirtualBody[] bodies, float deltaTime) { foreach (var otherBody in bodies) { if (body != otherBody) { Vector3 dir = (otherBody.position - body.position).normalized; float sqrDis = (body.position - otherBody.position).sqrMagnitude; Vector3 acceleration = (G * otherBody.mass / sqrDis) * dir; body.velocity += acceleration * deltaTime; } } }
public Vector3 CalcAccelerationAt(Vector3 point, VirtualBody bodyToIgnore = null) { Vector3 acceleration = Vector3.zero; foreach (VirtualBody body in vrBodies) { if (bodyToIgnore != body) { float sqrDst = (body.position - point).sqrMagnitude; Vector3 forceDir = (body.position - point).normalized; acceleration += forceDir * Universe.gravitationalConstant * body.mass / sqrDst; } } return(acceleration); }
private Vector3 CalculateAcceleration(VirtualBody body, VirtualBody[] celestialBodies, float timeStep, bool onlyStrongest = false) { Vector3 totalAcceleration = Vector3.zero; Vector3 strongestAcceleration = Vector3.zero; foreach (var otherBody in celestialBodies) { if (otherBody != body) { float sqrDst = (otherBody.position - body.position).sqrMagnitude; Vector3 forceDir = (otherBody.position - body.position).normalized; Vector3 acceleration = forceDir * Universe.gravitationalConstant * otherBody.mass / sqrDst; if (acceleration.sqrMagnitude > strongestAcceleration.sqrMagnitude && body != relativeObject) { body.parent = otherBody; strongestAcceleration = acceleration; } totalAcceleration += acceleration; } } return(onlyStrongest ? strongestAcceleration : totalAcceleration); }
void DrawOrbits() { TestObject[] bodies = FindObjectsOfType <TestObject>(); VirtualBody[] virtualBodies = new VirtualBody[bodies.Length]; Vector3[][] drawPoints = new Vector3[bodies.Length][]; int referenceFrameIndex = 0; Vector2 referenceBodyInitialPosition = Vector2.zero; // Initialize virtual bodies (don't want to move the actual bodies) for (int i = 0; i < virtualBodies.Length; i++) { virtualBodies[i] = new VirtualBody(bodies[i]); drawPoints[i] = new Vector3[numSteps]; if (bodies[i] == centralBody && relativeToBody) { referenceFrameIndex = i; referenceBodyInitialPosition = virtualBodies[i].position; } } // Simulate for (int step = 0; step < numSteps; step++) { Vector2 referenceBodyPosition = (relativeToBody) ? virtualBodies[referenceFrameIndex].position : Vector2.zero; // Update velocities for (int i = 0; i < virtualBodies.Length; i++) { virtualBodies[i].velocity += CalculateAcceleration(i, virtualBodies) * timeStep; } // Update positions for (int i = 0; i < virtualBodies.Length; i++) { Vector2 newPos = virtualBodies[i].position + virtualBodies[i].velocity * timeStep; virtualBodies[i].position = newPos; if (relativeToBody) { var referenceFrameOffset = referenceBodyPosition - referenceBodyInitialPosition; newPos -= referenceFrameOffset; } if (relativeToBody && i == referenceFrameIndex) { newPos = referenceBodyInitialPosition; } drawPoints[i][step] = newPos; } } // Draw paths for (int bodyIndex = 0; bodyIndex < virtualBodies.Length; bodyIndex++) { Color pathColour = bodies[bodyIndex].gameObject.GetComponentInChildren <SpriteRenderer>().color; // for (int i = 0; i < drawPoints[bodyIndex].Length - 1; i++) { Debug.DrawLine(drawPoints[bodyIndex][i], drawPoints[bodyIndex][i + 1], pathColour); } // Hide renderer LineRenderer lineRenderer = bodies[bodyIndex].gameObject.GetComponentInChildren <LineRenderer>(); if (lineRenderer) { lineRenderer.enabled = false; } } }
private void UpdateVirtualBodyPosition(VirtualBody targetBody) { targetBody.position = (targetBody.position + targetBody.velocity * Universe.physicsTimeStep); }
void DrawOrbits() { CelestialBody[] bodies = FindObjectsOfType <CelestialBody> (); var virtualBodies = new VirtualBody[bodies.Length]; var drawPoints = new Vector3[bodies.Length][]; int referenceFrameIndex = 0; Vector3 referenceBodyInitialPosition = Vector3.zero; // Initialize virtual bodies (don't want to move the actual bodies) for (int i = 0; i < virtualBodies.Length; i++) { virtualBodies[i] = new VirtualBody(bodies[i]); drawPoints[i] = new Vector3[numSteps]; if (bodies[i] == centralBody && relativeToBody) { referenceFrameIndex = i; referenceBodyInitialPosition = virtualBodies[i].position; } } // Simulate for (int step = 0; step < numSteps; step++) { Vector3 referenceBodyPosition = (relativeToBody) ? virtualBodies[referenceFrameIndex].position : Vector3.zero; // Update velocities for (int i = 0; i < virtualBodies.Length; i++) { virtualBodies[i].velocity += CalculateAcceleration(i, virtualBodies) * timeStep; } // Update positions for (int i = 0; i < virtualBodies.Length; i++) { Vector3 newPos = virtualBodies[i].position + virtualBodies[i].velocity * timeStep; virtualBodies[i].position = newPos; if (relativeToBody) { var referenceFrameOffset = referenceBodyPosition - referenceBodyInitialPosition; newPos -= referenceFrameOffset; } if (relativeToBody && i == referenceFrameIndex) { newPos = referenceBodyInitialPosition; } drawPoints[i][step] = newPos; } } // Draw paths for (int bodyIndex = 0; bodyIndex < virtualBodies.Length; bodyIndex++) { var pathColour = bodies[bodyIndex].gameObject.GetComponentInChildren <MeshRenderer> ().sharedMaterial.color; // if (useThickLines) { var lineRenderer = bodies[bodyIndex].gameObject.GetComponentInChildren <LineRenderer> (); lineRenderer.enabled = true; lineRenderer.positionCount = drawPoints[bodyIndex].Length; lineRenderer.SetPositions(drawPoints[bodyIndex]); lineRenderer.startColor = pathColour; lineRenderer.endColor = pathColour; lineRenderer.widthMultiplier = width; } else { for (int i = 0; i < drawPoints[bodyIndex].Length - 1; i++) { Debug.DrawLine(drawPoints[bodyIndex][i], drawPoints[bodyIndex][i + 1], pathColour); } // Hide renderer var lineRenderer = bodies[bodyIndex].gameObject.GetComponentInChildren <LineRenderer> (); if (lineRenderer) { lineRenderer.enabled = false; } } } }