Orbit Library
Comment: 'Boundary Condition Flags'
Boundary Condition Flags
-----------------------------
These values determine how simulation objects will
behave upon hitting the boundary of a simulation.
REVERSE = Velocity is negated in the direction corresponding to the boundary edge.
SLOW = Velocity is reduced by a factor of ten in the direction corresponding to the boundary edge.
STOP = Velocity is set to zero in the direction corresponding to the boundary edge.
-----------------------------
DO NOT EDIT THESE
Comment: 'Orbit Configuration'
Orbit Configuration
-----------------------------
These values determine how many Orbit
simulations you can run at once. You should
set these values to be as low as possible for your needs.
orbit_MAX_SIMULATIONS determines the maximum number of concurrent simulations you can perform
orbit_MAX_POINTS determines the maximum number of objects per simulation
Comment: 'Orbit Source Code'
Orbit Source Code
-----------------------------
DO NOT EDIT
Simulations
Source
Configuration
Orbit Configuration Values - Change me!
const int orbit_MAX_SIMULATIONS = 4;
const int orbit_MAX_POINTS = 10;
nbody2
Orbit Source
//Copyright (c) 2010 Azoth (Shane Grant)
// http://www.sc2mapster.com/assets/orbit/
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
const int nbody_EPS = 1; // minimum distance squared between any two bodies
// Mass properties
const int nbody_AFFECTED = 1;
const int nbody_AFFECTS = 2;
const int nbody_MOVABLE = 4;
// Simulation configuration options
const int nbody_USEHEIGHT = 1;
const int nbody_ISSUEORDER = 2;
const int nbody_BOUNDARY_REVERSE = 4;
const int nbody_BOUNDARY_SLOW = 8;
const int nbody_BOUNDARY_STOP = 16;
// Structs
struct nbody_Vector
{
fixed x;
fixed y;
fixed z;
};
struct nbody_Mass
{
unit m_unit;
point m_point;
fixed m_mass;
nbody_Vector m_position;
nbody_Vector m_velocity;
bool m_affectsOthers;
bool m_valid;
bool m_fixed;
int m_properties;
};
struct nbody_Simulation
{
// Timestep
fixed m_dt;
// Valid flag
bool m_valid;
// Simulation boundaries
fixed m_xMax;
fixed m_xMin;
fixed m_yMax;
fixed m_yMin;
fixed m_zMin;
fixed m_zMax;
// Array of simulation masses
nbody_Mass[orbit_MAX_POINTS] m_points;
// Temporary storage
nbody_Vector[orbit_MAX_POINTS] m_temp;
// Configuration
int m_configuration;
bool m_useHeight;
};
// Simulation array
nbody_Simulation[orbit_MAX_SIMULATIONS] nbody_simulations;
//
// Simulation constructor
// Creates a new nbody simulation with the specified configuration.
// Input
// simulationNumber - The index in the simulation array for this simulation
// timestep - The time in seconds between simulation updates
// boundary - A rectangular region specifying the boundary of this
// simulation (X and Y bounds)
// zMin - Minimum height for the simulation
// zMax - Maximum height for the simulation
// useHeight - Whether to include height (z-axis) in simulation.
// issueOrders - Whether the simulation should instantly move units
// or issue orders for them to move
// boundaryBehavior - The behavior to take when a mass hits a boundary
// Output
// void
//
void nbody_newSimulation( int simulationNumber, fixed timestep, region boundary,
fixed zMin, fixed zMax, bool useHeight,
bool issueOrders, int boundaryBehavior )
{
int index;
int configuration;
point regionPoint;
nbody_simulations[simulationNumber].m_valid = true;
nbody_simulations[simulationNumber].m_dt = timestep;
index = 0;
while( index < orbit_MAX_POINTS )
{
nbody_simulations[simulationNumber].m_points[index].m_valid = false;
index = index + 1;
}
// Get bounds
regionPoint = RegionGetBoundsMin( boundary );
nbody_simulations[simulationNumber].m_xMin = PointGetX( regionPoint );
nbody_simulations[simulationNumber].m_yMin = PointGetY( regionPoint );
regionPoint = RegionGetBoundsMax( boundary );
nbody_simulations[simulationNumber].m_xMax = PointGetX( regionPoint );
nbody_simulations[simulationNumber].m_yMax = PointGetY( regionPoint );
nbody_simulations[simulationNumber].m_zMax = zMax;
nbody_simulations[simulationNumber].m_zMin = zMin;
// Configuration
configuration = 0;
if( useHeight )
{
configuration |= nbody_USEHEIGHT;
}
if( issueOrders )
{
configuration |= nbody_ISSUEORDER;
}
configuration |= boundaryBehavior;
nbody_simulations[simulationNumber].m_configuration = configuration;
}
//
// Simulation destructor
// Marks resources used by a simulation as free.
// Input
// simulationNumber - The index in the simulation array for this simulation
// Output
// void
//
void nbody_deleteSimulation( int simulationNumber )
{
int index;
index = 0;
while( index < orbit_MAX_POINTS )
{
nbody_simulations[simulationNumber].m_points[index].m_valid = false;
index += 1;
}
nbody_simulations[simulationNumber].m_valid = false;
}
//
// findEmptyIndex
// Helper function that finds the first available index to insert a new mass.
// Input
// simulationNumber - The index in the simulation array for this simulation
// Output
// The position for the mass to be stored, or -1 if no room is available.
//
int nbody_findEmptyIndex( int simulationNumber )
{
int index;
index = 0;
while( index < orbit_MAX_POINTS )
{
if( !nbody_simulations[simulationNumber].m_points[index].m_valid )
{
return index;
}
index = index + 1;
}
return -1;
}
//
// addMassArtificial
// Adds an artificial mass to the simulation. Artificial masses are not linked
// to units or points and thus have no visual feedback in the game other than
// their effect on other simulation members.
// Input
// simulationNumber - The index in the simulation array for this simulation
// mass - The mass of this object
// initXVelocity - Initial velocity in the x direction
// initYVelocity - Initial velocity in the y direction
// initZVelocity - Initial velocity in the z direction
// initXPosition - Initial x position
// initYPosition - Initial y position
// initZPosition - Initial z position
// affected - Whether this mass affects other masses
// affectsOthers - Whether this mass is affected by other masses
// Output
// The index of the mass within the simulation, or -1 if no room was available.
//
int nbody_addMassArtificial( int simulationNumber, fixed mass,
fixed initXVelocity, fixed initYVelocity,
fixed initZVelocity, fixed initXPosition,
fixed initYPosition, fixed initZPosition,
bool affected, bool affectsOthers )
{
int index;
int properties;
index = nbody_findEmptyIndex( simulationNumber );
if( index < 0 )
{
// Simulation is all full up!
return index;
}
// Unit, mass, m_validity
nbody_simulations[simulationNumber].m_points[index].m_unit = null;
nbody_simulations[simulationNumber].m_points[index].m_point = null;
nbody_simulations[simulationNumber].m_points[index].m_mass = mass;
nbody_simulations[simulationNumber].m_points[index].m_valid = true;
// Properties
properties = 0;
if( affected )
{
properties |= nbody_AFFECTED;
}
if( affectsOthers )
{
properties |= nbody_AFFECTS;
}
nbody_simulations[simulationNumber].m_points[index].m_properties = properties;
// Position
nbody_simulations[simulationNumber].m_points[index].m_position.x =
initXPosition;
nbody_simulations[simulationNumber].m_points[index].m_position.y =
initYPosition;
nbody_simulations[simulationNumber].m_points[index].m_position.z =
initZPosition;
// Velocity
nbody_simulations[simulationNumber].m_points[index].m_velocity.x =
initXVelocity;
nbody_simulations[simulationNumber].m_points[index].m_velocity.y =
initYVelocity;
nbody_simulations[simulationNumber].m_points[index].m_velocity.z =
initZVelocity;
return index;
}
//
// Masses should generally be around 10,000
// At close distances ( 10 or less ) you can expect acceleration to be quite
// fast (on the order of 10 units/s^2
// while at large distances ( upwards of 100 units), expect much smaller
// values around 0.01
//
// Velocity values will change at the rate dependent on the acceleration,
// so choose initial values that will have time to be changed before the mass
// flies into infinity
//
// addMassFromUnit
// Adds a mass associated with a unit to the simulation. The initial position
// of this unit determines its internal initial position.
// Input
// simulationNumber - The index in the simulation array for this simulation
// mass - The mass of this object
// theUnit - Unit this mass is associated with
// initXVelocity - Initial velocity in the x direction
// initYVelocity - Initial velocity in the y direction
// initZVelocity - Initial velocity in the z direction
// affected - Whether this mass affects other masses
// affectsOthers - Whether this mass is affected by other masses
// movable - Whether the unit is capable of moving by itself
// Output
// The index of the mass within the simulation, or -1 if no room was available.
//
int nbody_addMassFromUnit( int simulationNumber, unit theUnit, fixed mass,
fixed initXVelocity, fixed initYVelocity,
fixed initZVelocity, bool affected, bool affectsOthers,
bool movable )
{
int index;
int properties;
point unitPosition;
index = nbody_findEmptyIndex( simulationNumber );
if( index < 0 )
{
// Simulation is all full up!
return index;
}
// Unit, mass, m_validity
nbody_simulations[simulationNumber].m_points[index].m_unit = theUnit;
nbody_simulations[simulationNumber].m_points[index].m_point = null;
nbody_simulations[simulationNumber].m_points[index].m_mass = mass;
nbody_simulations[simulationNumber].m_points[index].m_valid = true;
// Properties
properties = 0;
if( affected )
{
properties |= nbody_AFFECTED;
}
if( affectsOthers )
{
properties |= nbody_AFFECTS;
}
if( movable )
{
properties |= nbody_MOVABLE;
}
nbody_simulations[simulationNumber].m_points[index].m_properties = properties;
// Position
unitPosition = UnitGetPosition( theUnit );
nbody_simulations[simulationNumber].m_points[index].m_position.x =
PointGetX( unitPosition );
nbody_simulations[simulationNumber].m_points[index].m_position.y =
PointGetY( unitPosition );
nbody_simulations[simulationNumber].m_points[index].m_position.z =
UnitGetHeight( theUnit );
// Velocity
nbody_simulations[simulationNumber].m_points[index].m_velocity.x =
initXVelocity;
nbody_simulations[simulationNumber].m_points[index].m_velocity.y =
initYVelocity;
nbody_simulations[simulationNumber].m_points[index].m_velocity.z =
initZVelocity;
return index;
}
//
// addMassFromPoint
// Adds a mass associated with a point to the simulation. The initial position
// of this point determines its internal initial position.
// Input
// simulationNumber - The index in the simulation array for this simulation
// thePoint - The point for this object
// theUnit - Unit this mass is associated with
// initXVelocity - Initial velocity in the x direction
// initYVelocity - Initial velocity in the y direction
// initZVelocity - Initial velocity in the z direction
// affected - Whether this mass affects other masses
// affectsOthers - Whether this mass is affected by other masses
// movable - Whether the unit is capable of moving by itself
// Output
// The index of the mass within the simulation, or -1 if no room was available.
//
int nbody_addMassFromPoint( int simulationNumber, point thePoint, fixed mass,
fixed initXVelocity, fixed initYVelocity,
fixed initZVelocity, bool affected, bool affectsOthers,
bool movable )
{
int index;
int properties;
point unitPosition;
index = nbody_findEmptyIndex( simulationNumber );
if( index < 0 )
{
// Simulation is all full up!
return index;
}
// Unit, mass, m_validity
nbody_simulations[simulationNumber].m_points[index].m_unit = null;
nbody_simulations[simulationNumber].m_points[index].m_point = thePoint;
nbody_simulations[simulationNumber].m_points[index].m_mass = mass;
nbody_simulations[simulationNumber].m_points[index].m_valid = true;
// Properties
properties = 0;
if( affected )
{
properties |= nbody_AFFECTED;
}
if( affectsOthers )
{
properties |= nbody_AFFECTS;
}
if( movable )
{
properties |= nbody_MOVABLE;
}
nbody_simulations[simulationNumber].m_points[index].m_properties = properties;
// Position
nbody_simulations[simulationNumber].m_points[index].m_position.x =
PointGetX( thePoint );
nbody_simulations[simulationNumber].m_points[index].m_position.y =
PointGetY( thePoint );
nbody_simulations[simulationNumber].m_points[index].m_position.z =
PointGetHeight( thePoint );
// Velocity
nbody_simulations[simulationNumber].m_points[index].m_velocity.x =
initXVelocity;
nbody_simulations[simulationNumber].m_points[index].m_velocity.y =
initYVelocity;
nbody_simulations[simulationNumber].m_points[index].m_velocity.z =
initZVelocity;
return index;
}
//
// removeMass
// Removes a mass from a simulation
// Input
// simulationNumber - The index in the simulation array for this simulation
// massIndex - The index of the mass to remove
// Output
// void
//
void nbody_removeMass( int simulationNumber, int massIndex )
{
nbody_simulations[simulationNumber].m_points[massIndex].m_valid = false;
}
//
// updateSimulation
// Runs one timestep for the given simulation
// Input
// simulationNumber - The index in the simulation array for this simulation
// Output
// void
//
void nbody_updateSimulation( int simulationNumber )
{
int outerIndex;
int innerIndex;
fixed ax; // acceleration
fixed ay;
fixed az;
fixed dx; // position
fixed dy;
fixed dz;
fixed invr; // inverse distance
fixed f; // force
fixed dt; // timestep
bool useHeight;
bool moveUnits;
point massPosition;
unit theUnit;
if( !nbody_simulations[simulationNumber].m_valid )
{
return;
}
dt = nbody_simulations[simulationNumber].m_dt;
useHeight = ( ( nbody_simulations[simulationNumber].m_configuration & nbody_USEHEIGHT ) != 0 );
moveUnits = ( ( nbody_simulations[simulationNumber].m_configuration & nbody_ISSUEORDER ) != 0 );
// Update position of movable units
outerIndex = 0;
while( outerIndex < orbit_MAX_POINTS )
{
// If valid and a movable object, update internal position OR if it is valid, a unit, and we are issuing move orders
if( nbody_simulations[simulationNumber].m_points[outerIndex].m_valid &&
( ( ( nbody_simulations[simulationNumber].m_points[outerIndex].m_properties & nbody_MOVABLE ) != 0 ) ||
( nbody_simulations[simulationNumber].m_points[outerIndex].m_unit != null && moveUnits )
)
)
{
theUnit = nbody_simulations[simulationNumber].m_points[outerIndex].m_unit;
if( theUnit != null )
{
massPosition = UnitGetPosition( theUnit );
}
else
{
massPosition = nbody_simulations[simulationNumber].m_points[outerIndex].m_point;
}
if( massPosition != null )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.x =
PointGetX( massPosition );
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.y =
PointGetY( massPosition );
if( theUnit != null )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.z =
UnitGetHeight( theUnit );
}
else
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.y =
PointGetY( massPosition );
}
}
}
outerIndex += 1;
}
outerIndex = 0;
while( outerIndex < orbit_MAX_POINTS )
{
ax = 0.0;
ay = 0.0;
az = 0.0;
// Calculate force acting upon outerIndex by all other simulation objects
// if this is a valid point that can be affected
if( nbody_simulations[simulationNumber].m_points[outerIndex].m_valid &&
( ( nbody_simulations[simulationNumber].m_points[outerIndex].m_properties & nbody_AFFECTED ) != 0 )
)
{
innerIndex = 0;
while( innerIndex < orbit_MAX_POINTS )
{
// Only consider valid points that can affect others
if( nbody_simulations[simulationNumber].m_points[innerIndex].m_valid &&
( ( nbody_simulations[simulationNumber].m_points[innerIndex].m_properties & nbody_AFFECTS ) != 0 )
)
{
// Calculate distances
dx = nbody_simulations[simulationNumber].m_points[innerIndex].m_position.x -
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.x;
dy = nbody_simulations[simulationNumber].m_points[innerIndex].m_position.y -
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.y;
dz = nbody_simulations[simulationNumber].m_points[innerIndex].m_position.z -
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.z;
// Ignore height if configuration says so
if( !useHeight )
{
dz = 0;
}
// Assuming dx and dy are generally less than 1000, this value should fit into
// fixed without worrying about underflow
invr = 1.0 / SquareRoot( dx*dx + dy*dy + dz*dz + nbody_EPS );
// however, invr^3 will be too small in general, so we can't use it all at once
f = nbody_simulations[simulationNumber].m_points[innerIndex].m_mass * invr;
f = f * invr;
f = f * invr;
// Accumulate acceleration from gravitational attraction
ax = ax + f * dx;
ay = ay + f * dy;
az = az + f * dz;
}
else // not m_valid or does not affect others
{
// No changes to ax, ay, or az
}
innerIndex = innerIndex + 1;
}
// New positions
// the only worry here is for underflow in the 0.5*dt^2*ax term
// for the best simulation, we want dt to be as small as possible
// however, the smallest we can feasibly have it is around 0.2 assuming
// an acceleration term on the order of .01 - .1
nbody_simulations[simulationNumber].m_temp[outerIndex].x =
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.x +
dt * nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.x +
0.5 * dt * dt * ax;
nbody_simulations[simulationNumber].m_temp[outerIndex].y =
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.y +
dt * nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.y +
0.5 * dt * dt * ay;
nbody_simulations[simulationNumber].m_temp[outerIndex].z =
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.z +
dt * nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.z +
0.5 * dt * dt * az;
// New velocities
// not much to worry about here, if dt is on the order of anywhere
// from .03 to 1 and ax is .01 to .1, we won't underflow
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.x =
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.x +
dt * ax;
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.y =
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.y +
dt * ay;
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.z =
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.z +
dt * az;
}
else // not m_valid
{
// do nothing to update this particle
}
outerIndex = outerIndex + 1;
}
// Update positions
outerIndex = 0;
while( outerIndex < orbit_MAX_POINTS )
{
// Only update positions of masses that can be affected
if( nbody_simulations[simulationNumber].m_points[outerIndex].m_valid &&
( ( nbody_simulations[simulationNumber].m_points[outerIndex].m_properties & nbody_AFFECTED ) != 0 )
)
{
dx = nbody_simulations[simulationNumber].m_temp[outerIndex].x;
dy = nbody_simulations[simulationNumber].m_temp[outerIndex].y;
dz = nbody_simulations[simulationNumber].m_temp[outerIndex].z;
// Adjust for boundary conditions - x coordinate
if( dx > nbody_simulations[simulationNumber].m_xMax ||
dx < nbody_simulations[simulationNumber].m_xMin
)
{
// Set position to boundary
if( dx > nbody_simulations[simulationNumber].m_xMax )
{
dx = nbody_simulations[simulationNumber].m_xMax;
}
else
{
dx = nbody_simulations[simulationNumber].m_xMin;
}
// Update velocity
if( ( nbody_simulations[simulationNumber].m_configuration & nbody_BOUNDARY_REVERSE ) != 0 )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.x =
-nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.x;
}
else if( ( nbody_simulations[simulationNumber].m_configuration & nbody_BOUNDARY_SLOW ) != 0 )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.x =
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.x / 10.0;
}
else
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.x = 0.0;
}
}
// Adjust for boundary conditions - y coordinate
if( dy > nbody_simulations[simulationNumber].m_yMax ||
dy < nbody_simulations[simulationNumber].m_yMin
)
{
// Set position to boundary
if( dy > nbody_simulations[simulationNumber].m_yMax )
{
dy = nbody_simulations[simulationNumber].m_yMax;
}
else
{
dy = nbody_simulations[simulationNumber].m_yMin;
}
// Update velocity
if( ( nbody_simulations[simulationNumber].m_configuration & nbody_BOUNDARY_REVERSE ) != 0 )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.y =
-nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.y;
}
else if( ( nbody_simulations[simulationNumber].m_configuration & nbody_BOUNDARY_SLOW ) != 0 )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.y =
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.y / 10.0;
}
else
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.y = 0.0;
}
}
// Adjust for boundary conditions - z coordinate
if( useHeight &&
dz > nbody_simulations[simulationNumber].m_zMax ||
dz < nbody_simulations[simulationNumber].m_zMin
)
{
// Set position to boundary
if( dz > nbody_simulations[simulationNumber].m_zMax )
{
dz = nbody_simulations[simulationNumber].m_zMax;
}
else
{
dz = nbody_simulations[simulationNumber].m_zMin;
}
// Update velocity
if( ( nbody_simulations[simulationNumber].m_configuration & nbody_BOUNDARY_REVERSE ) != 0 )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.z =
-nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.z;
}
else if( ( nbody_simulations[simulationNumber].m_configuration & nbody_BOUNDARY_SLOW ) != 0 )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.z =
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.z / 10.0;
}
else
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_velocity.z = 0.0;
}
}
// Update internal position
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.x = dx;
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.y = dy;
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.z = dz;
// Update external position
if( nbody_simulations[simulationNumber].m_points[outerIndex].m_unit != null )
{
if( moveUnits )
{
UnitIssueOrder( nbody_simulations[simulationNumber].m_points[outerIndex].m_unit,
OrderTargetingPoint(AbilityCommand("move", 0),
Point( nbody_simulations[simulationNumber].m_points[outerIndex].m_position.x,
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.y )),
c_orderQueueReplace);
}
else
{
UnitSetPosition( nbody_simulations[simulationNumber].m_points[outerIndex].m_unit,
Point( nbody_simulations[simulationNumber].m_points[outerIndex].m_position.x,
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.y ),
false );
UnitSetHeight( nbody_simulations[simulationNumber].m_points[outerIndex].m_unit,
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.z,
0.0 );
}
}
else if( nbody_simulations[simulationNumber].m_points[outerIndex].m_point != null )
{
nbody_simulations[simulationNumber].m_points[outerIndex].m_point =
Point( nbody_simulations[simulationNumber].m_points[outerIndex].m_position.x,
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.y );
PointSetHeight( nbody_simulations[simulationNumber].m_points[outerIndex].m_point,
nbody_simulations[simulationNumber].m_points[outerIndex].m_position.z );
}
}
outerIndex = outerIndex + 1;
}
}
orbit_AddMassFromPoint
return nbody_addMassArtificial( lp_simulationNumber, lp_mass,
lp_initXVelocity, lp_initYVelocity,
lp_initZVelocity, lp_initXPosition,
lp_initYPosition, lp_initZPosition,
lp_affected, lp_affectsOthers );
orbit_UpdateSimulation
orbit_NewSimulation
orbit_AddMassFromUnit
return nbody_addMassArtificial( lp_simulationNumber, lp_mass,
lp_initXVelocity, lp_initYVelocity,
lp_initZVelocity, lp_initXPosition,
lp_initYPosition, lp_initZPosition,
lp_affected, lp_affectsOthers );
orbit_AddMassArtificial
return nbody_addMassArtificial( lp_simulationNumber, lp_mass,
lp_initXVelocity, lp_initYVelocity,
lp_initZVelocity, lp_initXPosition,
lp_initYPosition, lp_initZPosition,
lp_affected, lp_affectsOthers );
orbit_DeleteSimulation
return nbody_addMassFromPoint( lp_simulationNumber, lp_thePoint, lp_mass,
lp_initXVelocity, lp_initYVelocity,
lp_initZVelocity, lp_affected, lp_affectsOthers, lp_movable );
nbody_updateSimulation( lp_simulationIndex );
return nbody_addMassFromUnit( lp_simulationNumber, lp_theUnit, lp_mass,
lp_initXVelocity, lp_initYVelocity,
lp_initZVelocity, lp_affected, lp_affectsOthers, lp_movable );
nbody_deleteSimulation( lp_simulationIndex );
return nbody_addMassArtificial( lp_simulationNumber, lp_mass,
lp_initXVelocity, lp_initYVelocity,
lp_initZVelocity, PointGetX( lp_initPosition ),
PointGetY( lp_initPosition ), PointGetHeight( lp_initPosition ),
lp_affected, lp_affectsOthers );
nbody_newSimulation( lp_simulationIndex, lp_timestep, lp_boundary, lp_zMin, lp_zMax, lp_useHeight, lp_issueOrders, lp_boundaryBehavior );
false
0
false
0
0
0
0
false
0
0
false
0
0
0
false
0
false
0
0
false
0
0
0
0
0
0
0
0
false
false
false
initZVelocity
simulationNumber
affected
affected
movable
initPosition
zMax
initXVelocity
mass
initZVelocity
movable
useHeight
affectsOthers
affected
simulationIndex
initZVelocity
mass
affectsOthers
issueOrders
initXVelocity
mass
simulationIndex
initYVelocity
initXVelocity
theUnit
thePoint
affectsOthers
boundary
initYVelocity
simulationNumber
boundaryBehavior
timestep
initYVelocity
zMin
simulationNumber
simulationIndex
orbit_BOUNDARY_TYPE
REVERSE
4
SLOW
8
STOP
16