Merge branch 'master' into javascript-ai

Pull in coordinate precision
Fix Conflicts:
	src/Core/Entities/ShipEntity.m
This commit is contained in:
cim 2013-07-11 21:22:14 +01:00
commit 43f2efdcfb
72 changed files with 2689 additions and 1857 deletions

2
.gitignore vendored
View File

@ -26,3 +26,5 @@ obj.spk.dbg
DebugOXP/requires.plist
AddOns/
# Debug output
core

View File

@ -235,6 +235,7 @@ OOLITE_MATHS_FILES = \
CollisionRegion.m \
OOMeshToOctreeConverter.m \
Octree.m \
OOHPVector.m \
OOMatrix.m \
OOQuaternion.m \
OOVector.m \
@ -283,6 +284,7 @@ OOLITE_SCRIPTING_FILES = \
OOJSPlanet.m \
OOJSPlayer.m \
OOJSPlayerShip.m \
OOJSPopulatorDefinition.m \
OOJSQuaternion.m \
OOJSScript.m \
OOJSShip.m \

View File

@ -2,6 +2,7 @@
GLOBAL =
{
ENTER = (performIdle);
START_TUMBLING = (performBuoyTumble);
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage);
UPDATE = ("pauseAI: 3600");
};

View File

@ -460,6 +460,7 @@
universe.findSystems.badDistance = $error;
universe.populate = no; // “Populating a system with…” message when generating a star system
universe.populate.error = yes;
universe.populate.witchspace = inherit;
universe.setup.badStation = $scriptError; // Message generated if the main station turns out not to be a station (for instance, this could happen if a non-station ship had the role coriolis).
universe.maxEntitiesDump = no; // Dumps all entities when universe is full (Can be quite verbose)

View File

@ -115,6 +115,7 @@
"setCoordinatesFromPosition",
"performFaceDestination",
"performTumble",
"performBuoyTumble",
"fightOrFleeMissile",
"setCourseToPlanet",
"setTakeOffFromPlanet",

View File

@ -1,11 +1,18 @@
(
/* General */
"oolite-populator.js",
/* Interfaces */
"oolite-contracts-cargo.js",
"oolite-contracts-helpers.js",
"oolite-contracts-parcels.js",
"oolite-contracts-passengers.js",
/* Missions */
"oolite-constrictor-hunt-mission.js",
"oolite-cloaking-device-mission.js",
"oolite-nova-mission.js",
"oolite-thargoid-plans-mission.js",
"oolite-trumbles-mission.js",
"oolite-contracts-cargo.js",
"oolite-contracts-helpers.js",
"oolite-contracts-parcels.js",
"oolite-contracts-passengers.js"
"oolite-trumbles-mission.js"
)

View File

@ -0,0 +1,504 @@
/*
oolite-populator.js
Built-in system populator settings
Oolite
Copyright © 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
/*jslint white: true, undef: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */
/*global missionVariables, player*/
"use strict";
this.name = "oolite-populator";
this.author = "cim";
this.copyright = "© 2008-2013 the Oolite team.";
this.version = "1.79";
/* Basic system population */
this.systemWillPopulate = function()
{
/* Priority range 0-99 used by Oolite default populator */
/* Add navigation buoys */
// for the compass to work properly, the buoys need to be added first,
// in this order.
system.setPopulator("oolite-nav-buoy",
{
priority: 1,
location: "COORDINATES",
coordinates: system.mainStation.position.add(system.mainStation.vectorForward.multiply(10E3)),
callback: function(pos) {
var nb = system.addShips("buoy",1,pos,0)[0];
nb.scanClass = "CLASS_BUOY";
nb.reactToAIMessage("START_TUMBLING");
},
deterministic: true
});
system.setPopulator("oolite-witch-buoy",
{
priority: 2,
location: "COORDINATES",
coordinates: [0,0,0],
callback: function(pos) {
var wb = system.addShips("buoy-witchpoint",1,pos,0)[0];
wb.scanClass = "CLASS_BUOY";
wb.reactToAIMessage("START_TUMBLING");
},
deterministic: true
});
/* Calculate numbers of major groups */
var gov = system.info.government; // 0=anarchy, 7=corporate
var eco = system.info.economy; // 0=rich ind, 7=poor ag
/* Calculate traders */
var traders = 9 - eco;
if (gov == 0)
{
traders *= 1.25;
}
// randomise with centred distribution
traders = 1 + traders * (Math.random() + Math.random());
// trim if too many
while (traders > 15)
{
traders = 1+(Math.random()*traders);
}
traders = Math.floor(traders);
var pstraders = Math.floor((Math.random()*4) + (traders * (Math.random()*32) / 120));
/* Calculate pirates */
// more in more dangerous systems, more if more traders about
var pirates = ((traders/3)+Math.random()+Math.random())*(8-gov);
// randomise with centred distribution
pirates = 1 + pirates * (Math.random() + Math.random());
// trim if too many
while (pirates > 25)
{
pirates = 12+(Math.random()*pirates);
}
var pspirates = pirates * Math.random()*32/120;
/* old populator allocated these pirates individually to various
* packs. this populator doesn't make it easy to do this the same
* way so instead, divide the number of pirates by the expected
* pack size to get the number of packs */
pirates = Math.floor(pirates/2.5);
pspirates = Math.floor(pspirates/2.5);
/* Calculate bounty hunters */
var hunters = (1+gov)*(traders/8);
// more in anarchy
if (gov==0)
{
hunters *= 1.25;
}
// randomise with centred distribution
hunters = 1 + hunters * (Math.random() + Math.random());
// trim if too many
while (hunters > 15)
{
hunters = 5+(Math.random()*hunters);
}
hunters = Math.ceil(hunters);
var pshunters = Math.floor(hunters * Math.random()*32/160);
if (hunters+pirates+traders < 10)
{
// too quiet
hunters += 2;
pirates += 1;
traders += 2;
}
/* Calculate thargoids */
var thargoids = 0;
while (Math.random() < 0.065)
{
thargoids++;
}
/* Start adding ship groups */
/* Add traders */
system.setPopulator("oolite-route1-traders",
{
priority: 10,
location: "LANE_WP",
groupCount: traders,
callback: function(pos) {
var r1t = system.addShips("trader",1,pos,0)[0];
r1t.setBounty(0,"setup actions");
}
});
system.setPopulator("oolite-route2-traders",
{
priority: 10,
location: "LANE_PS",
groupCount: pstraders,
callback: function(pos) {
var r2t = system.addShips("sunskim-trader",1,pos,0)[0];
r2t.setBounty(0,"setup actions");
// ensure sufficient insulation
// tested at Aenqute - see [Universe makeSunSkimmer]
var reqInsulation = 1000/(1+r2t.maxSpeed);
if (reqInsulation > 12)
{
reqInsulation = 12;
// 12 is enough to survive indefinitely
// anywhere in non-nova systems
}
if (r2t.heatInsulation < reqInsulation)
{
r2t.heatInsulation = reqInsulation;
}
r2t.switchAI("route2sunskimAI.plist");
}
});
/* Add pirates */
system.setPopulator("oolite-route1-pirates",
{
priority: 10,
location: "LANE_WP",
groupCount: pirates,
callback: this._addPirates
});
system.setPopulator("oolite-route2-pirates",
{
priority: 10,
location: "LANE_PS",
groupCount: pspirates,
callback: this._addPirates
});
/* Add hunters */
var addHunter = function(pos)
{
if (Math.random()*8 < system.government)
{
// add police
if (Math.random()*8 < system.techLevel - 6)
{
var hunter = system.addShips("interceptor",1,pos,0)[0];
hunter.primaryRole = "police";
}
else
{
var hunter = system.addShips("police",1,pos,0)[0];
}
}
else
{
var hunter = system.addShips("hunter",1,pos,0)[0];
}
hunter.setBounty(0,"setup actions");
return hunter;
}
system.setPopulator("oolite-route1-hunters",
{
priority: 10,
location: "LANE_WP",
groupCount: hunters,
callback: addHunter
});
system.setPopulator("oolite-route2-hunters",
{
priority: 10,
location: "LANE_PS",
groupCount: hunters,
callback: function(pos) {
var hunter = addHunter(pos);
hunter.switchAI("route2patrolAI.plist");
hunter.AIState = (Math.random()<0.5)?"HEAD_FOR_PLANET":"HEAD_FOR_SUN";
}
});
/* Add thargoids */
system.setPopulator("oolite-route1-thargoids",
{
priority: 10,
location: "LANE_WP",
groupCount: thargoids,
callback: function(pos) {
system.addShips("thargoid",1,pos,0);
}
});
/* Add asteroids */
var clusters = 2*(1+Math.floor(system.scrambledPseudoRandomNumber(51728)*4));
var psclusters = 1+(clusters/2);
clusters = clusters-psclusters;
var addRockCluster = function(pos)
{
var size = 1+Math.floor(system.scrambledPseudoRandomNumber(Math.floor(pos.x))*11);
var hermit = (system.scrambledPseudoRandomNumber(Math.floor(pos.y))*31) <= size;
var rocks = system.addShips("asteroid",size,pos,25E3);
if (hermit)
{
var rh = system.addShips("rockhermit",1,pos,0)[0];
rh.scanClass = "CLASS_ROCK";
}
}
system.setPopulator("oolite-route1-asteroids",
{
priority: 10,
location: "LANE_WP",
locationSeed: 51728,
groupCount: clusters,
callback: addRockCluster,
deterministic: true
});
system.setPopulator("oolite-route2-asteroids",
{
priority: 10,
location: "LANE_PS",
locationSeed: 82715,
groupCount: psclusters,
callback: addRockCluster,
deterministic: true
});
/* To ensure there's at least one hermit, for pirates to dock at */
system.setPopulator("oolite-offlane-hermit",
{
priority: 99, // make sure all other core population is done
location: "PLANET_ORBIT_HIGH",
locationSeed: 71258,
groupCount: 1,
callback: function(pos) {
if (system.countShipsWithPrimaryRole("rockhermit")==0) {
var rh = system.addShips("rockhermit",1,pos,0)[0];
rh.scanClass = "CLASS_ROCK";
// just the hermit, no other rocks
}
},
deterministic: true
});
}
// function responsible for replenishing system contents
this.systemWillRepopulate = function()
{
if (system.sun.isGoingNova)
{
return;
}
// incoming traders, more frequent in rich economies
if (Math.random() < 0.06+0.01*(8-system.info.economy))
{
if (Math.random() < 0.2)
{
var newtrader = system.addShips("sunskim-trader",1,[0,0,0],7500)[0];
var reqIns = 1000/(1+newtrader.maxSpeed);
if (reqIns > 12)
{
reqIns = 12;
}
if (newtrader.heatInsulation < reqIns)
{
newtrader.heatInsulation = reqIns;
}
newtrader.switchAI("route2sunskimAI.plist");
}
else
{
var newtrader = system.addShips("trader",1,[0,0,0],7500)[0];
}
newtrader.setBounty(0,"setup actions");
return;
}
// replace lost patrols (more frequently in safe systems)
if (Math.random() < 0.05+0.02*(1+system.info.government))
{
var current = system.countShipsWithPrimaryRole("police");
var target = system.info.government;
if (current < target)
{
var newpolice = system.mainStation.launchShipWithRole("police");
if (Math.random() < 0.2)
{
newpolice.switchAI("route2patrolAI.plist");
}
else
{
newpolice.switchAI("route1patrolAI.plist");
}
newpolice.setBounty(0,"setup actions");
}
else
{
// enough police, add a bounty hunter instead?
current = system.countShipsWithPrimaryRole("hunter");
if (system.info.government <= 1)
{
target = 4;
}
else
{
target = system.info.government/2;
}
if (current < target)
{
var newhunter = system.addShips("hunter",1,[0,0,0],7500)[0];
if (Math.random() < 0.2)
{
newhunter.switchAI("route2patrolAI.plist");
}
newhunter.setBounty(0,"setup actions");
}
}
return;
}
// replace lost pirates
if (Math.random() < 0.02*(8-system.info.government))
{
var current = system.countShipsWithPrimaryRole("pirate");
var target = 3*(8-system.info.government);
if (current < target)
{
// temporary hack: pirates don't currently have the AI to fly
// to their raiding grounds, so for now just magically have
// them appear on the spacelane when the player isn't looking
do
{
if (Math.random() < 0.15)
{
var pos = Vector3D.interpolate(system.sun.position, system.mainPlanet.position, 0.3+Math.random()*0.5);
}
else
{
var pos = Vector3D.interpolate([0,0,0], system.mainPlanet.position, Math.random()*0.8);
}
}
while (pos.distanceTo(player.ship) < 51200);
this._addPirates(pos);
}
return;
}
// Thargoid invasions
if (Math.random() < 0.01)
{
system.addShips("thargoid",1,[0,0,0],7500);
}
}
/* And the equivalent functions for interstellar space */
this.interstellarSpaceWillPopulate = function()
{
log(this.name,"Interstellar populator");
system.setPopulator("oolite-interstellar-thargoids",
{
priority: 10,
location: "WITCHPOINT",
groupCount: 2+Math.floor(Math.random()*4),
callback: function(pos) {
system.addShips("thargoid",1,pos,0);
}
});
}
this.interstellarSpaceWillRepopulate = function()
{
if (system.countShipsWithPrimaryRole("thargoid") < 2)
{
if (Math.random() > 0.01)
{
system.addShips("thargoid",1,[0,0,0],25600);
}
else
{
// everyone's getting ambushed today
system.addShips("trader",1,[0,0,0],6400);
}
}
}
/* And finally the default nova system populators */
this.novaSystemWillPopulate = function()
{
log(this.name,"Nova populator");
// just burnt-out rubble
system.setPopulator("oolite-nova-cinders",
{
priority: 10,
location: "WITCHPOINT",
groupCount: 1,
callback: function(pos) {
system.addShips("cinder",10,pos,25600);
pos.z += 300000;
system.addShips("cinder",10,pos,25600);
}
});
}
/* // no repopulation is needed, but other OXPs could use this function
this.novaSystemWillRepopulate = function()
{
}
*/
/* Utility functions */
this._addPirates = function(pos)
{
var size = Math.random()*4;
if (system.government >= 6)
{
size = size/2;
}
else if (system.government <= 1)
{
size += Math.random()*3;
}
size = Math.ceil(size);
var pg = system.addGroup("pirate",size,pos,2.5E3);
for (var i=0;i<pg.ships.length;i++)
{
pg.ships[i].setBounty(20+system.government+size+Math.floor(Math.random()*8),"setup actions");
}
}

View File

@ -42,7 +42,7 @@ MA 02110-1301, USA.
BOOL isUniverse; // if YES location is origin and radius is 0.0f
int crid; // identifier
Vector location; // center of the region
HPVector location; // center of the region
GLfloat radius; // inner radius of the region
GLfloat border_radius; // additiønal, border radius of the region (typically 32km or some value > the scanner range)
@ -61,10 +61,10 @@ MA 02110-1301, USA.
}
- (id) initAsUniverse;
- (id) initAtLocation:(Vector) locn withRadius:(GLfloat) rad withinRegion:(CollisionRegion*) otherRegion;
- (id) initAtLocation:(HPVector) locn withRadius:(GLfloat) rad withinRegion:(CollisionRegion*) otherRegion;
- (void) clearSubregions;
- (void) addSubregionAtPosition:(Vector) pos withRadius:(GLfloat) rad;
- (void) addSubregionAtPosition:(HPVector) pos withRadius:(GLfloat) rad;
// collision checking
- (void) clearEntityList;

View File

@ -34,9 +34,9 @@ MA 02110-1301, USA.
#import "OODebugFlags.h"
static BOOL positionIsWithinRegion(Vector position, CollisionRegion *region);
static BOOL sphereIsWithinRegion(Vector position, GLfloat rad, CollisionRegion *region);
static BOOL positionIsWithinBorders(Vector position, CollisionRegion *region);
static BOOL positionIsWithinRegion(HPVector position, CollisionRegion *region);
static BOOL sphereIsWithinRegion(HPVector position, GLfloat rad, CollisionRegion *region);
static BOOL positionIsWithinBorders(HPVector position, CollisionRegion *region);
@implementation CollisionRegion
@ -74,7 +74,7 @@ static int crid_counter = 1;
}
- (id) initAtLocation:(Vector)locn withRadius:(GLfloat)rad withinRegion:(CollisionRegion *)otherRegion
- (id) initAtLocation:(HPVector)locn withRadius:(GLfloat)rad withinRegion:(CollisionRegion *)otherRegion
{
if ((self = [self init]))
{
@ -109,7 +109,7 @@ static int crid_counter = 1;
}
- (void) addSubregionAtPosition:(Vector)pos withRadius:(GLfloat)rad
- (void) addSubregionAtPosition:(HPVector)pos withRadius:(GLfloat)rad
{
// check if this can be fitted within any of the subregions
//
@ -139,12 +139,12 @@ static int crid_counter = 1;
// update routines to check if a position is within the radius or within its borders
//
static BOOL positionIsWithinRegion(Vector position, CollisionRegion *region)
static BOOL positionIsWithinRegion(HPVector position, CollisionRegion *region)
{
if (region == nil) return NO;
if (region->isUniverse) return YES;
Vector loc = region->location;
HPVector loc = region->location;
GLfloat r1 = region->radius;
if ((position.x < loc.x - r1)||(position.x > loc.x + r1)||
@ -158,12 +158,12 @@ static BOOL positionIsWithinRegion(Vector position, CollisionRegion *region)
}
static BOOL sphereIsWithinRegion(Vector position, GLfloat rad, CollisionRegion *region)
static BOOL sphereIsWithinRegion(HPVector position, GLfloat rad, CollisionRegion *region)
{
if (region == nil) return NO;
if (region->isUniverse) return YES;
Vector loc = region->location;
HPVector loc = region->location;
GLfloat r1 = region->radius;
if ((position.x - rad < loc.x - r1)||(position.x + rad > loc.x + r1)||
@ -177,12 +177,12 @@ static BOOL sphereIsWithinRegion(Vector position, GLfloat rad, CollisionRegion *
}
static BOOL positionIsWithinBorders(Vector position, CollisionRegion *region)
static BOOL positionIsWithinBorders(HPVector position, CollisionRegion *region)
{
if (region == nil) return NO;
if (region->isUniverse) return YES;
Vector loc = region->location;
HPVector loc = region->location;
GLfloat r1 = region->radius + region->border_radius;
if ((position.x < loc.x - r1)||(position.x > loc.x + r1)||
@ -229,7 +229,7 @@ static BOOL positionIsWithinBorders(Vector position, CollisionRegion *region)
- (BOOL) checkEntity:(Entity *)ent
{
Vector position = ent->position;
HPVector position = ent->position;
// check subregions
CollisionRegion *sub = nil;
@ -264,7 +264,7 @@ static BOOL positionIsWithinBorders(Vector position, CollisionRegion *region)
// According to Shark, when this was in Universe this was where Oolite spent most time!
//
Entity *e1, *e2;
Vector p1, p2;
HPVector p1;
double dist2, r1, r2, r0, min_dist2;
unsigned i;
Entity *entities_to_test[n_entities];
@ -323,10 +323,9 @@ static BOOL positionIsWithinBorders(Vector position, CollisionRegion *region)
{
checks_this_tick++;
p2 = vector_subtract(e2->position, p1);
r2 = e2->collision_radius;
r0 = r1 + r2;
dist2 = magnitude2(p2);
dist2 = HPdistance2(e2->position, p1);
min_dist2 = r0 * r0;
if (dist2 < PROXIMITY_WARN_DISTANCE2 * min_dist2)
{
@ -451,15 +450,15 @@ static BOOL entityByEntityOcclusionToValue(Entity *e1, Entity *e2, OOSunEntity *
// return NO; // things already /in/ shade can't shade things more.
//
// check projected sizes of discs
GLfloat d2_sun = distance2(e1->position, the_sun->position);
GLfloat d2_e2sun = distance2(e2->position, the_sun->position);
GLfloat d2_sun = HPdistance2(e1->position, the_sun->position);
GLfloat d2_e2sun = HPdistance2(e2->position, the_sun->position);
if (d2_e2sun > d2_sun)
{
// you are nearer the sun than the potential occluder, so it can't shade you
return NO;
}
GLfloat d2_e2 = distance2( e1->position, e2->position);
GLfloat d2_e2 = HPdistance2( e1->position, e2->position);
GLfloat cr_sun = the_sun->collision_radius;
GLfloat cr2_sun_scaled = cr_sun * cr_sun * d2_e2 / d2_sun;
@ -475,13 +474,13 @@ static BOOL entityByEntityOcclusionToValue(Entity *e1, Entity *e2, OOSunEntity *
// find the difference between the angles subtended by occluder and sun
float theta_diff = asin(cr_e2 / sqrt(d2_e2)) - asin(cr_sun / sqrt(d2_sun));
Vector p_sun = the_sun->position;
Vector p_e2 = e2->position;
Vector p_e1 = e1->position;
Vector v_sun = vector_subtract(p_sun, p_e1);
HPVector p_sun = the_sun->position;
HPVector p_e2 = e2->position;
HPVector p_e1 = e1->position;
Vector v_sun = HPVectorToVector(HPvector_subtract(p_sun, p_e1));
v_sun = vector_normal_or_zbasis(v_sun);
Vector v_e2 = vector_subtract(p_e2, p_e1);
Vector v_e2 = HPVectorToVector(HPvector_subtract(p_e2, p_e1));
v_e2 = vector_normal_or_xbasis(v_e2);
float phi = acos(dot_product(v_sun, v_e2)); // angle between sun and e2 from e1's viewpoint

View File

@ -108,7 +108,7 @@ MA 02110-1301, USA.
if (isDockingStation && [player status] == STATUS_IN_FLIGHT &&
[player getDockingClearanceStatus] >= DOCKING_CLEARANCE_STATUS_REQUESTED)
{
if (magnitude2(vector_subtract([player position], [self absolutePositionForSubentity])) > 2250000) // within 1500m of the dock
if (HPmagnitude2(HPvector_subtract([player position], [self absolutePositionForSubentity])) > 2250000) // within 1500m of the dock
{
[station sendExpandedMessage:@"[station-docking-clearance-abort-cancelled]" toShip:player];
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
@ -275,19 +275,19 @@ MA 02110-1301, USA.
NSNumber *shipID = [NSNumber numberWithUnsignedShort:ship_id];
StationEntity *station = (StationEntity *)[self parentEntity];
Vector launchVector = vector_forward_from_quaternion(quaternion_multiply(orientation, [station orientation]));
Vector temp = (fabs(launchVector.x) < 0.8)? make_vector(1,0,0) : make_vector(0,1,0);
temp = cross_product(launchVector, temp); // 90 deg to launchVector & temp
Vector vi = cross_product(launchVector, temp);
Vector vj = cross_product(launchVector, vi);
Vector vk = launchVector;
HPVector launchVector = HPvector_forward_from_quaternion(quaternion_multiply(orientation, [station orientation]));
HPVector temp = (fabs(launchVector.x) < 0.8)? make_HPvector(1,0,0) : make_HPvector(0,1,0);
temp = HPcross_product(launchVector, temp); // 90 deg to launchVector & temp
HPVector vi = HPcross_product(launchVector, temp);
HPVector vj = HPcross_product(launchVector, vi);
HPVector vk = launchVector;
// check if this is a new ship on approach
//
if (![shipsOnApproach objectForKey:shipID])
{
Vector delta = vector_subtract([ship position], [self absolutePositionForSubentity]);
float ship_distance = magnitude(delta);
HPVector delta = HPvector_subtract([ship position], [self absolutePositionForSubentity]);
float ship_distance = HPmagnitude(delta);
if (ship_distance > SCANNER_MAX_RANGE)
{
@ -300,12 +300,12 @@ MA 02110-1301, USA.
if (ship_distance < 1000.0 + [station collisionRadius] + ship->collision_radius) // too close - back off
return OOMakeDockingInstructions(station, [self absolutePositionForSubentity], 0, 5000, @"BACK_OFF", nil, NO);
float dot = dot_product(launchVector, delta);
float dot = HPdot_product(launchVector, delta);
if (dot < 0) // approaching from the wrong side of the station - construct a vector to the side of the station.
{
Vector approachVector = cross_product(vector_normal(delta), launchVector);
approachVector = cross_product(launchVector, approachVector); // vector, 90 degr rotated from launchVector towards target.
return OOMakeDockingInstructions(station, OOVectorTowards([self absolutePositionForSubentity], approachVector, [station collisionRadius] + 5000) , 0, 1000, @"APPROACH", nil, NO);
HPVector approachVector = HPcross_product(HPvector_normal(delta), launchVector);
approachVector = HPcross_product(launchVector, approachVector); // vector, 90 degr rotated from launchVector towards target.
return OOMakeDockingInstructions(station, OOHPVectorTowards([self absolutePositionForSubentity], approachVector, [station collisionRadius] + 5000) , 0, 1000, @"APPROACH", nil, NO);
}
if (ship_distance > 12500.0)
@ -342,22 +342,22 @@ MA 02110-1301, USA.
float rangeAdvised = [nextCoords oo_floatForKey:@"range"];
// calculate world coordinates from relative coordinates
Vector rel_coords;
rel_coords.x = [nextCoords oo_floatForKey:@"rx"];
rel_coords.y = [nextCoords oo_floatForKey:@"ry"];
rel_coords.z = [nextCoords oo_floatForKey:@"rz"];
Vector coords = [self absolutePositionForSubentity];
HPVector rel_coords;
rel_coords.x = [nextCoords oo_doubleForKey:@"rx"];
rel_coords.y = [nextCoords oo_doubleForKey:@"ry"];
rel_coords.z = [nextCoords oo_doubleForKey:@"rz"];
HPVector coords = [self absolutePositionForSubentity];
coords.x += rel_coords.x * vi.x + rel_coords.y * vj.x + rel_coords.z * vk.x;
coords.y += rel_coords.x * vi.y + rel_coords.y * vj.y + rel_coords.z * vk.y;
coords.z += rel_coords.x * vi.z + rel_coords.y * vj.z + rel_coords.z * vk.z;
// check if the ship is at the control point
double max_allowed_range = 2.0 * rangeAdvised + ship->collision_radius; // maximum distance permitted from control point - twice advised range
Vector delta = vector_subtract(ship->position, coords);
HPVector delta = HPvector_subtract(ship->position, coords);
if (magnitude2(delta) > max_allowed_range * max_allowed_range) // too far from the coordinates - do not remove them from the stack!
if (HPmagnitude2(delta) > max_allowed_range * max_allowed_range) // too far from the coordinates - do not remove them from the stack!
{
if ((docking_stage == 1) &&(magnitude2(delta) < 1000000.0)) // 1km*1km
if ((docking_stage == 1) &&(HPmagnitude2(delta) < 1000000.0)) // 1km*1km
speedAdvised *= 0.5; // half speed
return OOMakeDockingInstructions(station, coords, speedAdvised, rangeAdvised, @"APPROACH_COORDINATES", nil, NO);
@ -450,11 +450,11 @@ MA 02110-1301, USA.
NSNumber *shipID = [NSNumber numberWithUnsignedShort:[ship universalID]];
StationEntity *station = (StationEntity *)[self parentEntity];
Vector launchVector = vector_forward_from_quaternion(quaternion_multiply(orientation, [station orientation]));
Vector temp = (fabs(launchVector.x) < 0.8)? make_vector(1,0,0) : make_vector(0,1,0);
temp = cross_product(launchVector, temp); // 90 deg to launchVector & temp
Vector rightVector = cross_product(launchVector, temp);
Vector upVector = cross_product(launchVector, rightVector);
HPVector launchVector = HPvector_forward_from_quaternion(quaternion_multiply(orientation, [station orientation]));
HPVector temp = (fabs(launchVector.x) < 0.8)? make_HPvector(1,0,0) : make_HPvector(0,1,0);
temp = HPcross_product(launchVector, temp); // 90 deg to launchVector & temp
HPVector rightVector = HPcross_product(launchVector, temp);
HPVector upVector = HPcross_product(launchVector, rightVector);
// will select a direction for offset based on the entity personality (was ship ID)
int offset_id = [ship entityPersonalityInt] & 0xf; // 16 point compass
@ -462,18 +462,18 @@ MA 02110-1301, USA.
float s = sin(offset_id * M_PI * ONE_EIGHTH);
// test if this points at the ship
Vector point1 = [self absolutePositionForSubentity];
HPVector point1 = [self absolutePositionForSubentity];
point1.x += launchVector.x * corridor_offset[corridor_count - 1];
point1.y += launchVector.x * corridor_offset[corridor_count - 1];
point1.z += launchVector.x * corridor_offset[corridor_count - 1];
Vector alt1 = point1;
HPVector alt1 = point1;
point1.x += c * upVector.x * corridor_offset[corridor_count - 1] + s * rightVector.x * corridor_offset[corridor_count - 1];
point1.y += c * upVector.y * corridor_offset[corridor_count - 1] + s * rightVector.y * corridor_offset[corridor_count - 1];
point1.z += c * upVector.z * corridor_offset[corridor_count - 1] + s * rightVector.z * corridor_offset[corridor_count - 1];
alt1.x -= c * upVector.x * corridor_offset[corridor_count - 1] + s * rightVector.x * corridor_offset[corridor_count - 1];
alt1.y -= c * upVector.y * corridor_offset[corridor_count - 1] + s * rightVector.y * corridor_offset[corridor_count - 1];
alt1.z -= c * upVector.z * corridor_offset[corridor_count - 1] + s * rightVector.z * corridor_offset[corridor_count - 1];
if (distance2(alt1, ship->position) < distance2(point1, ship->position))
if (HPdistance2(alt1, ship->position) < HPdistance2(point1, ship->position))
{
s = -s;
c = -c; // turn 180 degrees
@ -578,7 +578,7 @@ MA 02110-1301, USA.
if ([player status] == STATUS_IN_FLIGHT &&
[player getDockingClearanceStatus] >= DOCKING_CLEARANCE_STATUS_REQUESTED)
{
if (magnitude2(vector_subtract([player position], [self absolutePositionForSubentity])) > 2250000) // within 1500m of the dock
if (HPmagnitude2(HPvector_subtract([player position], [self absolutePositionForSubentity])) > 2250000) // within 1500m of the dock
{
[[self parentEntity] sendExpandedMessage:@"[station-docking-clearance-abort-cancelled]" toShip:player];
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
@ -661,7 +661,7 @@ MA 02110-1301, USA.
Vector vj = vector_up_from_quaternion(q0);
Vector vk = vector_forward_from_quaternion(q0);
Vector port_pos = [self absolutePositionForSubentity];
HPVector port_pos = [self absolutePositionForSubentity];
BoundingBox shipbb = [ship boundingBox];
BoundingBox arbb = [ship findBoundingBoxRelativeToPosition: port_pos InVectors: vi : vj : vk];
@ -710,9 +710,9 @@ MA 02110-1301, USA.
{ // launch-only dock: will collide!
[ship takeScrapeDamage: 5 * [UNIVERSE getTimeDelta]*[ship flightSpeed] from:station];
// and bounce
Vector rel = vector_subtract([ship position],port_pos);
rel = vector_multiply_scalar(vector_normal(rel),[ship flightSpeed]*0.4);
[ship adjustVelocity:rel];
HPVector rel = HPvector_subtract([ship position],port_pos);
rel = HPvector_multiply_scalar(HPvector_normal(rel),[ship flightSpeed]*0.4);
[ship adjustVelocity:HPVectorToVector(rel)];
if (arbb.max.z < 0.0)
{ // give some warning before exploding...
@ -762,7 +762,7 @@ MA 02110-1301, USA.
}
// adjust the ship back to the center of the port
Vector pos = [ship position];
HPVector pos = [ship position];
pos.x -= delta.y * vj.x + delta.x * vi.x;
pos.y -= delta.y * vj.y + delta.x * vi.y;
pos.z -= delta.y * vj.z + delta.x * vi.z;
@ -823,7 +823,7 @@ MA 02110-1301, USA.
BoundingBox bb = [ship boundingBox];
StationEntity *station = (StationEntity *)[self parentEntity];
Vector launchPos = [self absolutePositionForSubentity];
HPVector launchPos = [self absolutePositionForSubentity];
Vector launchVel = [station velocity];
double launchSpeed = 0.5 * [ship maxFlightSpeed];
if ([station maxFlightSpeed] > 0 && [station flightSpeed] > 0) // is self a carrier in flight.
@ -948,24 +948,24 @@ MA 02110-1301, USA.
for (i = 0; (i < ship_count)&&(isEmpty); i++)
{
ShipEntity* ship = (ShipEntity*)my_entities[i];
double d2 = distance2([station position], [ship position]);
double d2 = HPdistance2([station position], [ship position]);
if ((ship != station) && (d2 < 25000000)&&([ship status] != STATUS_DOCKED)) // within 5km
{
Vector ppos = [self absolutePositionForSubentity];
d2 = distance2(ppos, ship->position);
HPVector ppos = [self absolutePositionForSubentity];
d2 = HPdistance2(ppos, ship->position);
if (d2 < 4000000) // within 2km of the port entrance
{
Quaternion q1 = [station orientation];
q1 = quaternion_multiply([self orientation], q1);
//
Vector v_out = vector_forward_from_quaternion(q1);
Vector r_pos = make_vector(ship->position.x - ppos.x, ship->position.y - ppos.y, ship->position.z - ppos.z);
HPVector v_out = HPvector_forward_from_quaternion(q1);
HPVector r_pos = make_HPvector(ship->position.x - ppos.x, ship->position.y - ppos.y, ship->position.z - ppos.z);
if (r_pos.x||r_pos.y||r_pos.z)
r_pos = vector_normal(r_pos);
r_pos = HPvector_normal(r_pos);
else
r_pos.z = 1.0;
//
double vdp = dot_product(v_out, r_pos); //== cos of the angle between r_pos and v_out
double vdp = HPdot_product(v_out, r_pos); //== cos of the angle between r_pos and v_out
//
if (vdp > 0.86)
{
@ -1007,15 +1007,15 @@ MA 02110-1301, USA.
for (i = 0; i < ship_count; i++)
{
ShipEntity *ship = (ShipEntity*)my_entities[i];
double d2 = distance2([station position], [ship position]);
double d2 = HPdistance2([station position], [ship position]);
if ((ship != station)&&(d2 < 25000000)&&([ship status] != STATUS_DOCKED)) // within 5km
{
Vector ppos = [self absolutePositionForSubentity];
HPVector ppos = [self absolutePositionForSubentity];
float time_out = -15.00; // 15 secs
do
{
isClear = YES;
d2 = distance2(ppos, ship->position);
d2 = HPdistance2(ppos, ship->position);
if (d2 < 4000000) // within 2km of the port entrance
{
Quaternion q1 = [station orientation];
@ -1040,8 +1040,8 @@ MA 02110-1301, USA.
}
if (time_out > 0)
{
Vector v1 = vector_forward_from_quaternion(orientation);
Vector spos = ship->position;
HPVector v1 = HPvector_forward_from_quaternion(orientation);
HPVector spos = ship->position;
spos.x += 3000.0 * v1.x; spos.y += 3000.0 * v1.y; spos.z += 3000.0 * v1.z;
[ship setPosition:spos]; // move 3km out of the way
}
@ -1071,15 +1071,15 @@ MA 02110-1301, USA.
port_dimensions = make_vector(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z);
}
Vector vk = vector_forward_from_quaternion(orientation);
HPVector vk = HPvector_forward_from_quaternion(orientation);
BoundingBox stbb = [station boundingBox];
Vector start = position;
HPVector start = position;
while ((start.x > stbb.min.x)&&(start.x < stbb.max.x) &&
(start.y > stbb.min.y)&&(start.y < stbb.max.y) &&
(start.z > stbb.min.z)&&(start.z < stbb.max.z) )
{
start = vector_add(start, vector_multiply_scalar(vk, port_dimensions.z));
start = HPvector_add(start, HPvector_multiply_scalar(vk, port_dimensions.z));
}
port_corridor = start.z - position.z;

View File

@ -52,7 +52,6 @@ MA 02110-1301, USA.
@end
#if OO_SHADERS
enum
{
@ -151,6 +150,10 @@ enum
- (void) update:(OOTimeDelta) delta_t
{
// [self setPosition:position];
HPVector c_pos = [PLAYER viewpointPosition];
cameraRelativePosition = make_vector((OOScalar)-fmod(c_pos.x,DUST_SCALE),(OOScalar)-fmod(c_pos.y,DUST_SCALE),(OOScalar)-fmod(c_pos.z,DUST_SCALE));
#if OO_SHADERS
if (EXPECT_NOT(shaderMode == kShaderModeUnknown)) [self checkShaderMode];
@ -163,7 +166,7 @@ enum
zero_distance = 0.0;
Vector offset = [player position];
Vector offset = vector_flip(cameraRelativePosition);
GLfloat half_scale = DUST_SCALE * 0.50;
int vi;
for (vi = 0; vi < DUST_N_PARTICLES; vi++)
@ -228,10 +231,12 @@ enum
return shader;
}
- (Vector) offsetPlayerPosition
{
return vector_subtract([PLAYER position], make_vector(DUST_SCALE * 0.5f, DUST_SCALE * 0.5f, DUST_SCALE * 0.5f));
// used as shader uniform, so needs to be low precision
HPVector c_pos = [PLAYER viewpointPosition];
Vector offset = make_vector((OOScalar)fmod(c_pos.x,DUST_SCALE),(OOScalar)fmod(c_pos.y,DUST_SCALE),(OOScalar)fmod(c_pos.z,DUST_SCALE));
return vector_subtract(offset, make_vector(DUST_SCALE * 0.5f, DUST_SCALE * 0.5f, DUST_SCALE * 0.5f));
}

View File

@ -108,7 +108,8 @@ enum OOScanClass
GLfloat cam_zero_distance;
GLfloat no_draw_distance; // 10 km initially
GLfloat collision_radius;
Vector position;
HPVector position; // use high-precision vectors for global position
Vector cameraRelativePosition;
Quaternion orientation;
int zero_index;
@ -127,7 +128,7 @@ enum OOScanClass
CollisionRegion *collisionRegion; // initially nil - then maintained
@protected
Vector lastPosition;
HPVector lastPosition;
Quaternion lastOrientation;
GLfloat distanceTravelled; // set to zero initially
@ -197,12 +198,15 @@ enum OOScanClass
- (ShipEntity *) parentEntity; // owner if self is subentity of owner, otherwise nil.
- (ShipEntity *) rootShipEntity; // like parentEntity, but recursive.
- (void) setPosition:(Vector)posn;
- (void) setPositionX:(GLfloat)x y:(GLfloat)y z:(GLfloat)z;
- (Vector) position;
- (void) setPosition:(HPVector)posn;
- (void) setPositionX:(OOHPScalar)x y:(OOHPScalar)y z:(OOHPScalar)z;
- (HPVector) position;
- (Vector) cameraRelativePosition;
// gets a low-position relative vector
- (Vector) vectorTo:(Entity *)entity;
- (Vector) absolutePositionForSubentity;
- (Vector) absolutePositionForSubentityOffset:(Vector) offset;
- (HPVector) absolutePositionForSubentity;
- (HPVector) absolutePositionForSubentityOffset:(HPVector) offset;
- (double) zeroDistance;
- (double) camZeroDistance;

View File

@ -56,6 +56,7 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
@interface Entity (OOPrivate)
- (BOOL) checkLinkedLists;
- (void) updateCameraRelativePosition;
@end
@ -71,7 +72,7 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
orientation = kIdentityQuaternion;
rotMatrix = kIdentityMatrix;
position = kZeroVector;
position = kZeroHPVector;
no_draw_distance = 100000.0; // 10 km
@ -112,7 +113,7 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
- (NSString *)descriptionComponents
{
return [NSString stringWithFormat:@"position: %@ scanClass: %@ status: %@", VectorDescription([self position]), OOStringFromScanClass([self scanClass]), OOStringFromEntityStatus([self status])];
return [NSString stringWithFormat:@"position: %@ scanClass: %@ status: %@", HPVectorDescription([self position]), OOStringFromScanClass([self scanClass]), OOStringFromEntityStatus([self status])];
}
@ -591,48 +592,66 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
}
- (Vector) position
- (HPVector) position
{
return position;
}
- (Vector) cameraRelativePosition
{
return cameraRelativePosition;
}
// Exposed to uniform bindings.
// so needs to remain at OpenGL precision levels
- (Vector) relativePosition
{
return vector_subtract([self position], [PLAYER position]);
return HPVectorToVector(HPvector_subtract([self position], [PLAYER position]));
}
- (Vector) vectorTo:(Entity *)entity
{
return HPVectorToVector(HPvector_subtract([entity position], [self position]));
}
- (void) setPosition:(Vector) posn
- (void) setPosition:(HPVector) posn
{
position = posn;
[self updateCameraRelativePosition];
}
- (void) setPositionX:(GLfloat)x y:(GLfloat)y z:(GLfloat)z
- (void) setPositionX:(OOHPScalar)x y:(OOHPScalar)y z:(OOHPScalar)z
{
position.x = x;
position.y = y;
position.z = z;
[self updateCameraRelativePosition];
}
- (void) updateCameraRelativePosition
{
cameraRelativePosition = HPVectorToVector(HPvector_subtract([self absolutePositionForSubentity],[PLAYER viewpointPosition]));
}
- (Vector) absolutePositionForSubentity
- (HPVector) absolutePositionForSubentity
{
return [self absolutePositionForSubentityOffset:kZeroVector];
return [self absolutePositionForSubentityOffset:kZeroHPVector];
}
- (Vector) absolutePositionForSubentityOffset:(Vector) offset
- (HPVector) absolutePositionForSubentityOffset:(HPVector) offset
{
Vector abspos = vector_add(position, OOVectorMultiplyMatrix(offset, rotMatrix));
HPVector abspos = HPvector_add(position, OOHPVectorMultiplyMatrix(offset, rotMatrix));
Entity *last = nil;
Entity *father = [self parentEntity];
while (father != nil && father != last)
{
abspos = vector_add(OOVectorMultiplyMatrix(abspos, [father drawRotationMatrix]), [father position]);
abspos = HPvector_add(OOHPVectorMultiplyMatrix(abspos, [father drawRotationMatrix]), [father position]);
last = father;
if (![last isSubEntity]) break;
father = [father owner];
@ -816,8 +835,8 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
- (void) moveForward:(double)amount
{
Vector forward = vector_multiply_scalar(vector_forward_from_quaternion(orientation), amount);
position = vector_add(position, forward);
HPVector forward = HPvector_multiply_scalar(HPvector_forward_from_quaternion(orientation), amount);
position = HPvector_add(position, forward);
distanceTravelled += amount;
}
@ -837,14 +856,14 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
- (OOMatrix) transformationMatrix
{
OOMatrix result = rotMatrix;
return OOMatrixTranslate(result, position);
return OOMatrixHPTranslate(result, position);
}
- (OOMatrix) drawTransformationMatrix
{
OOMatrix result = rotMatrix;
return OOMatrixTranslate(result, position);
return OOMatrixHPTranslate(result, position);
}
@ -880,25 +899,28 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
{
zero_distance = [[self owner] zeroDistance];
cam_zero_distance = [[self owner] camZeroDistance];
[self updateCameraRelativePosition];
}
else
{
zero_distance = distance2(PLAYER->position, position);
cam_zero_distance = distance2([PLAYER viewpointPosition], position);
zero_distance = HPdistance2(PLAYER->position, position);
cam_zero_distance = HPdistance2([PLAYER viewpointPosition], position);
[self updateCameraRelativePosition];
}
}
else
{
zero_distance = magnitude2(position);
zero_distance = HPmagnitude2(position);
cam_zero_distance = zero_distance;
cameraRelativePosition = HPVectorToVector(position);
}
if ([self status] != STATUS_COCKPIT_DISPLAY)
{
position = vector_add(position, vector_multiply_scalar(velocity, delta_t));
position = HPvector_add(position, HPvector_multiply_scalar(vectorToHPVector(velocity), delta_t));
}
hasMoved = !vector_equal(position, lastPosition);
hasMoved = !HPvector_equal(position, lastPosition);
hasRotated = !quaternion_equal(orientation, lastOrientation);
lastPosition = position;
lastOrientation = orientation;
@ -959,7 +981,7 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
OOLog(@"dumpState.entity", @"Universal ID: %u", universalID);
OOLog(@"dumpState.entity", @"Scan class: %@", OOStringFromScanClass(scanClass));
OOLog(@"dumpState.entity", @"Status: %@", OOStringFromEntityStatus([self status]));
OOLog(@"dumpState.entity", @"Position: %@", VectorDescription(position));
OOLog(@"dumpState.entity", @"Position: %@", HPVectorDescription(position));
OOLog(@"dumpState.entity", @"Orientation: %@", QuaternionDescription(orientation));
OOLog(@"dumpState.entity", @"Distance travelled: %g", distanceTravelled);
OOLog(@"dumpState.entity", @"Energy: %g of %g", energy, maxEnergy);
@ -1024,7 +1046,7 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
{
NSString *result = [self descriptionForObjDumpBasic];
result = [result stringByAppendingFormat:@" range: %g (visible: %@)", distance([self position], [PLAYER position]), [self isVisible] ? @"yes" : @"no"];
result = [result stringByAppendingFormat:@" range: %g (visible: %@)", HPdistance([self position], [PLAYER position]), [self isVisible] ? @"yes" : @"no"];
return result;
}

View File

@ -97,19 +97,19 @@ MA 02110-1301, USA.
// http://aegidian.org/bb/viewtopic.php?f=3&t=13619 - CIM
if (cam_zero_distance > (clipradius+1000)*(clipradius+1000))
{
if (![UNIVERSE viewFrustumIntersectsSphereAt:position withRadius:clipradius])
if (![UNIVERSE viewFrustumIntersectsSphereAt:cameraRelativePosition withRadius:clipradius])
{
return;
}
}
}
else
else // is subentity
{
// don't bother with frustum culling within 1km, as above - CIM
if (cam_zero_distance > (collision_radius+1000)*(collision_radius+1000))
{
// check correct sub-entity position
if (![UNIVERSE viewFrustumIntersectsSphereAt:[self absolutePositionForSubentity] withRadius:[self collisionRadius]])
if (![UNIVERSE viewFrustumIntersectsSphereAt:cameraRelativePosition withRadius:[self collisionRadius]])
{
return;
}

View File

@ -29,7 +29,7 @@ MA 02110-1301, USA.
typedef struct
{
double timeframe; // universal time for this frame
Vector position;
HPVector position;
Quaternion orientation;
Vector k; // direction vectors
} Frame;
@ -45,7 +45,8 @@ enum
{
@private
Vector _exhaustScale;
GLfloat _vertices[34 * 3];
OOHPScalar _vertices[34 * 3];
GLfloat _glVertices[34 * 3];
GLfloat _exhaustBaseColors[34 * 4];
Frame _track[kExhaustFrameCount];
OOTimeAbsolute _trackTime;

View File

@ -29,6 +29,7 @@ MA 02110-1301, USA.
#import "ShipEntity.h"
#import "Universe.h"
#import "OOMacroOpenGL.h"
#import "PlayerEntity.h"
#import "OOTexture.h"
#import "OOGraphicsResetManager.h"
@ -73,7 +74,7 @@ static OOTexture *sPlumeTexture = nil;
if ((self = [super init]))
{
[self setOwner:ship];
Vector pos = { [definition oo_floatAtIndex:0], [definition oo_floatAtIndex:1], [definition oo_floatAtIndex:2] };
HPVector pos = { [definition oo_floatAtIndex:0], [definition oo_floatAtIndex:1], [definition oo_floatAtIndex:2] };
[self setPosition:pos];
Vector scale = { [definition oo_floatAtIndex:3], [definition oo_floatAtIndex:4], [definition oo_floatAtIndex:5] };
_exhaustScale = scale;
@ -147,7 +148,7 @@ static OOTexture *sPlumeTexture = nil;
if ((int)(ranrot_rand() % 25) < dam - 75)
flare_factor = 0.0;
Vector currentPos = ship->position;
HPVector currentPos = ship->position;
Vector vfwd = [ship forwardVector];
GLfloat spd = 0.5 * [ship flightSpeed];
vfwd = vector_multiply_scalar(vfwd, spd);
@ -156,7 +157,7 @@ static OOTexture *sPlumeTexture = nil;
vi = master_i;
vj = [ship upVector];
vk = [ship forwardVector];
zero.position = make_vector(currentPos.x + vi.x * position.x + vj.x * position.y + vk.x * position.z,
zero.position = make_HPvector(currentPos.x + vi.x * position.x + vj.x * position.y + vk.x * position.z,
currentPos.y + vi.y * position.x + vj.y * position.y + vk.y * position.z,
currentPos.z + vi.z * position.x + vj.z * position.y + vk.z * position.z);
@ -335,6 +336,23 @@ GLfloat pA[6] = { 0.01, 0.0, 2.0, 4.0, 6.0, 10.0 }; // phase adjustments
OOGL(glPopMatrix()); // restore absolute positioning
OOGL(glPushMatrix()); // avoid stack underflow
// GLTranslateOOVector(vector_flip([self cameraRelativePosition]));
HPVector cam = [PLAYER viewpointPosition];
for (unsigned n=0;n<34*3;n++)
{
switch (n%3)
{
case 0: // x coordinates
_glVertices[n] = (GLfloat)(_vertices[n] - cam.x);
break;
case 1: // y coordinates
_glVertices[n] = (GLfloat)(_vertices[n] - cam.y);
break;
case 2: // z coordinates
_glVertices[n] = (GLfloat)(_vertices[n] - cam.z);
break;
}
}
OOGL(glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT));
@ -349,7 +367,7 @@ GLfloat pA[6] = { 0.01, 0.0, 2.0, 4.0, 6.0, 10.0 }; // phase adjustments
OOGL(glShadeModel(GL_SMOOTH));
OOGL(glEnableClientState(GL_COLOR_ARRAY));
OOGL(glVertexPointer(3, GL_FLOAT, 0, _vertices));
OOGL(glVertexPointer(3, GL_FLOAT, 0, _glVertices));
OOGL(glColorPointer(4, GL_FLOAT, 0, _exhaustBaseColors));
double intpart, dphase = 1.0-modf((double)[UNIVERSE getTime]*2.5,&intpart);
@ -451,7 +469,11 @@ GLfloat pA[6] = { 0.01, 0.0, 2.0, 4.0, 6.0, 10.0 }; // phase adjustments
ShipEntity *ship = [self owner];
// Absolute position of self
Vector framePos = OOVectorMultiplyMatrix([self position], [ship drawTransformationMatrix]);
// normally this would use the transformation matrix, but that
// introduces inaccuracies
// so just use the rotation matrix, then translate using HPVectors
HPVector framePos = OOHPVectorMultiplyMatrix([self position], [ship drawRotationMatrix]);
framePos = HPvector_add(framePos,[ship position]);
Frame frame = { [UNIVERSE getTime], framePos, [ship normalOrientation], [ship upVector] };
_track[_nextFrame] = frame;
@ -496,7 +518,7 @@ GLfloat pA[6] = { 0.01, 0.0, 2.0, 4.0, 6.0, 10.0 }; // phase adjustments
// interpolate
double f1 = 1.0 - f0;
Vector posn;
HPVector posn;
posn.x = f0 * frame_zero.position.x + f1 * frame_one.position.x;
posn.y = f0 * frame_zero.position.y + f1 * frame_one.position.y;
posn.z = f0 * frame_zero.position.z + f1 * frame_one.position.z;
@ -526,7 +548,7 @@ GLfloat pA[6] = { 0.01, 0.0, 2.0, 4.0, 6.0, 10.0 }; // phase adjustments
_track[_nextFrame] = frame;
_nextFrame = (_nextFrame + 1) % kExhaustFrameCount;*/
_nextFrame = 0;
Vector framePos = OOVectorMultiplyMatrix([self position], [[self owner] drawTransformationMatrix]);
HPVector framePos = OOHPVectorMultiplyMatrix([self position], [[self owner] drawTransformationMatrix]);
uint8_t i;
for (i = 0; i < kExhaustFrameCount; i++)
{

View File

@ -36,7 +36,7 @@ MA 02110-1301, USA.
}
+ (instancetype) explosionFlashFromEntity:(Entity *)entity;
+ (instancetype) laserFlashWithPosition:(Vector)position velocity:(Vector)vel color:(OOColor *)color;
+ (instancetype) laserFlashWithPosition:(HPVector)position velocity:(Vector)vel color:(OOColor *)color;
+ (void) setUpTexture;

View File

@ -44,7 +44,7 @@ static OOTexture *sFlashTexture = nil;
@interface OOFlashEffectEntity (Private)
// Designated initializer.
- (id) initWithPosition:(Vector)pos size:(float)size color:(OOColor *)color duration:(float)duration;
- (id) initWithPosition:(HPVector)pos size:(float)size color:(OOColor *)color duration:(float)duration;
+ (void) resetGraphicsState;
@ -55,7 +55,7 @@ static OOTexture *sFlashTexture = nil;
@implementation OOFlashEffectEntity
- (id) initExplosionFlashWithPosition:(Vector)pos velocity:(Vector)vel size:(float)size
- (id) initExplosionFlashWithPosition:(HPVector)pos velocity:(Vector)vel size:(float)size
{
if ((self = [self initWithPosition:pos size:size color:[OOColor whiteColor] duration:kExplosionFlashDuration]))
{
@ -66,7 +66,7 @@ static OOTexture *sFlashTexture = nil;
}
- (id) initLaserFlashWithPosition:(Vector)pos velocity:(Vector)vel color:(OOColor *)color
- (id) initLaserFlashWithPosition:(HPVector)pos velocity:(Vector)vel color:(OOColor *)color
{
if ((self = [self initWithPosition:pos size:kLaserFlashInitialSize color:color duration:kLaserFlashDuration]))
{
@ -82,13 +82,13 @@ static OOTexture *sFlashTexture = nil;
}
+ (instancetype) laserFlashWithPosition:(Vector)pos velocity:(Vector)vel color:(OOColor *)color
+ (instancetype) laserFlashWithPosition:(HPVector)pos velocity:(Vector)vel color:(OOColor *)color
{
return [[[self alloc] initLaserFlashWithPosition:pos velocity:vel color:color] autorelease];
}
- (id) initWithPosition:(Vector)pos size:(float)size color:(OOColor *)color duration:(float)duration
- (id) initWithPosition:(HPVector)pos size:(float)size color:(OOColor *)color duration:(float)duration
{
if ((self = [super initWithDiameter:size]))
{

View File

@ -65,12 +65,12 @@ static OOTexture *sShotTexture2 = nil;
if (ship == srcEntity)
{
// main laser offset
position = vector_add([ship position], OOVectorMultiplyMatrix(offset, [ship drawRotationMatrix]));
[self setPosition:HPvector_add([ship position], vectorToHPVector(OOVectorMultiplyMatrix(offset, [ship drawRotationMatrix])))];
}
else
{
// subentity laser
position = [srcEntity absolutePositionForSubentityOffset:middle];
[self setPosition:[srcEntity absolutePositionForSubentityOffset:vectorToHPVector(middle)]];
}
Quaternion q = kIdentityQuaternion;
@ -162,7 +162,7 @@ static OOTexture *sShotTexture2 = nil;
velocity in -[Entity update:], which is considered sufficient for
NPC ships.
*/
position = vector_add([ship position], OOVectorMultiplyMatrix(_offset, [ship drawRotationMatrix]));
position = HPvector_add([ship position], vectorToHPVector(OOVectorMultiplyMatrix(_offset, [ship drawRotationMatrix])));
[self setOrientation:quaternion_multiply(_relOrientation, [ship normalOrientation])];
}

View File

@ -111,24 +111,24 @@ static OOTexture *sBlobTexture = nil;
Entity *father = [self owner];
Entity *last = nil;
Vector abspos = position;
HPVector abspos = position;
while (father != nil && father != last && father != NO_TARGET)
{
OOMatrix rM = [father drawRotationMatrix];
abspos = vector_add(OOVectorMultiplyMatrix(abspos, rM), [father position]);
abspos = HPvector_add(OOHPVectorMultiplyMatrix(abspos, rM), [father position]);
last = father;
if (![father isSubEntity]) break;
father = [father owner];
}
OOMatrix temp_matrix = OOMatrixLoadGLMatrix(GL_MODELVIEW_MATRIX);
OOGL(glPopMatrix()); OOGL(glPushMatrix()); // restore zero!
GLTranslateOOVector(abspos); // move to absolute position
GLTranslateOOVector(HPVectorToVector(HPvector_subtract(abspos,[PLAYER viewpointPosition]))); // move to camera-relative position
[self drawImmediate:immediate translucent:translucent];
GLLoadOOMatrix(temp_matrix);
}

View File

@ -56,7 +56,7 @@ enum
/* Initialize particle effect with particles flying out randomly.
Initiali _particleSize[] is equal to speed.
*/
- (id) initWithPosition:(Vector)position
- (id) initWithPosition:(HPVector)position
velocity:(Vector)velocity
count:(unsigned)count
minSpeed:(float)minSpeed

View File

@ -47,7 +47,7 @@ MA 02110-1301, USA.
/* Initialize shared aspects of the fragburst entities.
Also stashes generated particle speeds in _particleSize[] array.
*/
- (id) initWithPosition:(Vector)pos
- (id) initWithPosition:(HPVector)pos
velocity:(Vector)vel
count:(unsigned)count
minSpeed:(float)minSpeed
@ -60,7 +60,8 @@ MA 02110-1301, USA.
if ((self = [super init]))
{
_count = count;
position = pos;
[self setPosition:pos];
velocity = vel;
_duration = duration;
_maxSpeed = maxSpeed;
@ -151,8 +152,8 @@ do { \
OOGL(glEnable(GL_BLEND));
OOGL(glBlendFunc(GL_SRC_ALPHA, GL_ONE));
Vector viewPosition = [PLAYER viewpointPosition];
Vector selfPosition = [self position];
HPVector viewPosition = [PLAYER viewpointPosition];
HPVector selfPosition = [self position];
unsigned i, count = _count;
Vector *particlePosition = _particlePosition;
@ -216,7 +217,7 @@ do { \
{
OOGL(glPushMatrix());
GLTranslateOOVector(particlePosition[i]);
GLMultOOMatrix(OOMatrixForBillboard(vector_add(selfPosition, vector_multiply_scalar(particlePosition[i], individuality)), viewPosition));
GLMultOOMatrix(OOMatrixForBillboard(HPvector_add(selfPosition, vectorToHPVector(vector_multiply_scalar(particlePosition[i], individuality))), viewPosition));
glColor4fv(particleColor[i]);
OOGLBEGIN(GL_QUADS);
@ -254,7 +255,7 @@ do { \
@implementation OOSmallFragmentBurstEntity: OOParticleSystem
- (id) initFragmentBurstFrom:(Vector)fragPosition velocity:(Vector)fragVelocity size:(GLfloat)size
- (id) initFragmentBurstFrom:(HPVector)fragPosition velocity:(Vector)fragVelocity size:(GLfloat)size
{
enum
{
@ -313,7 +314,7 @@ do { \
@implementation OOBigFragmentBurstEntity: OOParticleSystem
- (id) initFragmentBurstFrom:(Vector)fragPosition velocity:(Vector)fragVelocity size:(GLfloat)size
- (id) initFragmentBurstFrom:(HPVector)fragPosition velocity:(Vector)fragVelocity size:(GLfloat)size
{
float minSpeed = 1.0f + size * 0.5f;
float maxSpeed = minSpeed * 4.0f;

View File

@ -478,7 +478,7 @@ static OOColor *ColorWithHSBColor(Vector c)
if (translucent || [UNIVERSE breakPatternHide]) return; // DON'T DRAW
if (_miniature && ![self isFinishedLoading]) return; // For responsiveness, don't block to draw as miniature.
if (![UNIVERSE viewFrustumIntersectsSphereAt:position withRadius:([self radius] + ATMOSPHERE_DEPTH)])
if (![UNIVERSE viewFrustumIntersectsSphereAt:cameraRelativePosition withRadius:([self radius] + ATMOSPHERE_DEPTH)])
{
// Don't draw
return;

View File

@ -28,6 +28,6 @@ MA 02110-1301, USA.
@interface OOPlasmaBurstEntity: OOLightParticleEntity
- (id) initWithPosition:(Vector)position;
- (id) initWithPosition:(HPVector)position;
@end

View File

@ -34,7 +34,7 @@ MA 02110-1301, USA.
@implementation OOPlasmaBurstEntity
- (id) initWithPosition:(Vector)inPosition
- (id) initWithPosition:(HPVector)inPosition
{
if ((self = [super initWithDiameter:kPlasmaBurstInitialSize]))
{

View File

@ -32,7 +32,7 @@ MA 02110-1301, USA.
OOTimeDelta _duration;
}
- (id) initWithPosition:(Vector)position
- (id) initWithPosition:(HPVector)position
velocity:(Vector)velocity
energy:(float)energy
duration:(OOTimeDelta)duration

View File

@ -43,7 +43,7 @@ MA 02110-1301, USA.
@implementation OOPlasmaShotEntity
- (id) initWithPosition:(Vector)inPosition
- (id) initWithPosition:(HPVector)inPosition
velocity:(Vector)inVelocity
energy:(float)inEnergy
duration:(OOTimeDelta)duration

View File

@ -33,7 +33,7 @@ MA 02110-1301, USA.
GLfloat _duration, _timeRemaining;
}
- (id) initWithPosition:(Vector)position
- (id) initWithPosition:(HPVector)position
velocity:(Vector)velocity
duration:(OOTimeDelta)duration
size:(float)size

View File

@ -38,7 +38,7 @@ MA 02110-1301, USA.
@implementation OOSparkEntity
- (id) initWithPosition:(Vector)pos
- (id) initWithPosition:(HPVector)pos
velocity:(Vector)vel
duration:(OOTimeDelta)duration
size:(float)size

View File

@ -200,7 +200,7 @@ MA 02110-1301, USA.
- (NSString*) descriptionComponents
{
NSString *result = [NSString stringWithFormat:@"ID: %u position: %@ radius: %.3fkm", [self universalID], VectorDescription([self position]), 0.001 * [self radius]];
NSString *result = [NSString stringWithFormat:@"ID: %u position: %@ radius: %.3fkm", [self universalID], HPVectorDescription([self position]), 0.001 * [self radius]];
if ([self goneNova])
{
result = [result stringByAppendingString:@" (gone nova)"];
@ -678,10 +678,10 @@ MA 02110-1301, USA.
}
- (void) setPosition:(Vector) posn
- (void) setPosition:(HPVector) posn
{
[super setPosition: posn];
[UNIVERSE setMainLightPosition: posn];
[UNIVERSE setMainLightPosition: HPVectorToVector(posn)];
}

View File

@ -285,7 +285,7 @@ MA 02110-1301, USA.
- (BOOL) setUpOneFlasher:(NSDictionary *) subentDict
{
OOFlasherEntity *flasher = [OOFlasherEntity flasherWithDictionary:subentDict];
[flasher setPosition:[subentDict oo_vectorForKey:@"position"]];
[flasher setPosition:[subentDict oo_hpvectorForKey:@"position"]];
[self addSubEntity:flasher];
return YES;
}
@ -295,7 +295,7 @@ MA 02110-1301, USA.
{
OOVisualEffectEntity *subentity = nil;
NSString *subentKey = nil;
Vector subPosition;
HPVector subPosition;
Quaternion subOrientation;
subentKey = [subentDict oo_stringForKey:@"subentity_key"];
@ -310,7 +310,7 @@ MA 02110-1301, USA.
return NO;
}
subPosition = [subentDict oo_vectorForKey:@"position"];
subPosition = [subentDict oo_hpvectorForKey:@"position"];
subOrientation = [subentDict oo_quaternionForKey:@"orientation"];
[subentity setPosition:subPosition];
@ -334,7 +334,7 @@ MA 02110-1301, USA.
[subEntities addObject:sub];
[sub setOwner:self];
double distance = magnitude([sub position]) + [sub findCollisionRadius];
double distance = HPmagnitude([sub position]) + [sub findCollisionRadius];
if (distance > _profileRadius)
{
_profileRadius = distance;
@ -391,8 +391,8 @@ MA 02110-1301, USA.
return; // TOO FAR AWAY
}
OOGL(glPushMatrix());
GLTranslateOOVector(position);
// HPVect: camera position
GLTranslateOOVector(HPVectorToVector(position));
GLMultOOMatrix(rotMatrix);
[self drawImmediate:immediate translucent:translucent];
@ -410,7 +410,7 @@ MA 02110-1301, USA.
Entity<OOSubEntity> *se = nil;
foreach (se, [self subEntities])
{
[se setPosition:vector_multiply_scalar([se position], factor)];
[se setPosition:HPvector_multiply_scalar([se position], factor)];
[se rescaleBy:factor];
}
@ -457,7 +457,7 @@ MA 02110-1301, USA.
GLfloat flasher_factor = pow(factor/scaleX,1.0/3.0);
foreach (se, [self subEntities])
{
Vector move = [se position];
HPVector move = [se position];
move.x *= factor/scaleX;
[se setPosition:move];
if ([se isVisualEffect])
@ -488,7 +488,7 @@ MA 02110-1301, USA.
GLfloat flasher_factor = pow(factor/scaleY,1.0/3.0);
foreach (se, [self subEntities])
{
Vector move = [se position];
HPVector move = [se position];
move.y *= factor/scaleY;
[se setPosition:move];
if ([se isVisualEffect])
@ -519,7 +519,7 @@ MA 02110-1301, USA.
GLfloat flasher_factor = pow(factor/scaleZ,1.0/3.0);
foreach (se, [self subEntities])
{
Vector move = [se position];
HPVector move = [se position];
move.z *= factor/scaleZ;
[se setPosition:move];
if ([se isVisualEffect])

View File

@ -608,7 +608,7 @@ static const BaseFace kTexturedFaces[][3] =
default:
typeString = @"UNKNOWN";
}
return [NSString stringWithFormat:@"ID: %u position: %@ type: %@ radius: %.3fkm", [self universalID], VectorDescription([self position]), typeString, 0.001 * [self radius]];
return [NSString stringWithFormat:@"ID: %u position: %@ type: %@ radius: %.3fkm", [self universalID], HPVectorDescription([self position]), typeString, 0.001 * [self radius]];
}
@ -649,7 +649,7 @@ static const BaseFace kTexturedFaces[][3] =
#ifndef NDEBUG
if ([ship reportAIMessages])
{
Vector p1 = ship->position;
HPVector p1 = ship->position;
OOLog(@"planet.collide.shipHit", @"DEBUG: %@ %d collided with planet at (%.1f,%.1f,%.1f)",[ship name], [ship universalID], p1.x,p1.y,p1.z);
}
#endif
@ -729,7 +729,7 @@ static const BaseFace kTexturedFaces[][3] =
}
- (void) setPosition:(Vector)posn
- (void) setPosition:(HPVector)posn
{
position = posn;
[atmosphere setPosition:posn];
@ -769,7 +769,7 @@ static const BaseFace kTexturedFaces[][3] =
// for some reason this check doesn't work when extremely close to
// the planet and with the horizon near the side of the frame (FP
// inaccuracy?)
if (![UNIVERSE viewFrustumIntersectsSphereAt:position withRadius:radWithAtmosphere])
if (![UNIVERSE viewFrustumIntersectsSphereAt:cameraRelativePosition withRadius:radWithAtmosphere])
{
// Don't draw
return;
@ -979,7 +979,7 @@ static const BaseFace kTexturedFaces[][3] =
{
OOGL(glPopMatrix()); // get old draw matrix back
OOGL(glPushMatrix()); // and store it again
OOGL(glTranslatef(position.x,position.y,position.z)); // centre on the planet
OOGL(glTranslatef(cameraRelativePosition.x,cameraRelativePosition.y,cameraRelativePosition.z)); // centre on the planet
// rotate
// GLMultOOMatrix([atmosphere rotationMatrix]);
// draw atmosphere entity
@ -1170,7 +1170,7 @@ static const BaseFace kTexturedFaces[][3] =
{
ShipEntity *shuttle_ship;
Quaternion q1;
Vector launch_pos = position;
HPVector launch_pos = position;
double start_distance = collision_radius + 125.0;
quaternion_set_random(&q1);

View File

@ -834,8 +834,8 @@ typedef enum
- (NSString *)customViewDescription;
- (void)resetCustomView;
- (void)setCustomViewDataFromDictionary:(NSDictionary*) viewDict;
- (Vector) viewpointPosition;
- (Vector) breakPatternPosition;
- (HPVector) viewpointPosition;
- (HPVector) breakPatternPosition;
- (Vector) viewpointOffset;
- (Vector) viewpointOffsetAft;
- (Vector) viewpointOffsetForward;

View File

@ -2161,6 +2161,9 @@ static GLfloat sBaseMass = 0.0;
galaxy_coordinates.y = system_seed.b;
[UNIVERSE setUpSpace];
// run initial system population
[UNIVERSE populateNormalSpace];
[self setDockTarget:[UNIVERSE station]];
// send world script events to let oxps know we're in a new system.
// all player.ship properties are still disabled at this stage.
@ -2311,7 +2314,7 @@ static GLfloat sBaseMass = 0.0;
// scanner sanity check - lose any targets further than maximum scanner range
ShipEntity *primeTarget = [self primaryTarget];
if (primeTarget && distance2([primeTarget position], [self position]) > SCANNER_MAX_RANGE2 && !autopilot_engaged)
if (primeTarget && HPdistance2([primeTarget position], [self position]) > SCANNER_MAX_RANGE2 && !autopilot_engaged)
{
[UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
[self removeTarget:primeTarget];
@ -2344,7 +2347,7 @@ static GLfloat sBaseMass = 0.0;
- (void) updateMovementFlags{
hasMoved = !vector_equal(position, lastPosition);
hasMoved = !HPvector_equal(position, lastPosition);
hasRotated = !quaternion_equal(orientation, lastOrientation);
lastPosition = position;
lastOrientation = orientation;
@ -2590,7 +2593,7 @@ static GLfloat sBaseMass = 0.0;
UPDATE_STAGE(@"applying newtonian drift");
assert(VELOCITY_CLEANUP_FULL > VELOCITY_CLEANUP_MIN);
position = vector_add(position, vector_multiply_scalar(velocity, (float)delta_t));
position = HPvector_add(position, vectorToHPVector(vector_multiply_scalar(velocity, (float)delta_t)));
GLfloat thrust_factor = 1.0;
if (flightSpeed > maxFlightSpeed)
@ -3040,7 +3043,8 @@ static GLfloat sBaseMass = 0.0;
- (OOMatrix) drawTransformationMatrix
{
OOMatrix result = playerRotMatrix;
return OOMatrixTranslate(result, position);
// HPVect: modify to use camera-relative positioning
return OOMatrixTranslate(result, HPVectorToVector(position));
}
@ -3059,13 +3063,13 @@ static GLfloat sBaseMass = 0.0;
- (void) moveForward:(double) amount
{
distanceTravelled += (float)amount;
position = vector_add(position, vector_multiply_scalar(v_forward, (float)amount));
position = HPvector_add(position, vectorToHPVector(vector_multiply_scalar(v_forward, (float)amount)));
}
- (Vector) breakPatternPosition
- (HPVector) breakPatternPosition
{
return vector_add(position,quaternion_rotate_vector(quaternion_conjugate(orientation),forwardViewOffset));
return HPvector_add(position,vectorToHPVector(quaternion_rotate_vector(quaternion_conjugate(orientation),forwardViewOffset)));
}
@ -3121,9 +3125,9 @@ static GLfloat sBaseMass = 0.0;
/* TODO post 1.78: profiling suggests this gets called often enough
* that it's worth caching the result per-frame - CIM */
- (Vector) viewpointPosition
- (HPVector) viewpointPosition
{
Vector viewpoint = position;
HPVector viewpoint = position;
Vector offset = [self viewpointOffset];
// FIXME: this ought to be done with matrix or quaternion functions.
@ -4462,12 +4466,12 @@ static GLfloat sBaseMass = 0.0;
// override ShipEntity definition to ensure that
// if shields are still up, always hit the main entity and take the damage
// on the shields
- (GLfloat) doesHitLine:(Vector)v0 :(Vector)v1 :(ShipEntity **)hitEntity
- (GLfloat) doesHitLine:(HPVector)v0 :(HPVector)v1 :(ShipEntity **)hitEntity
{
if (hitEntity)
hitEntity[0] = (ShipEntity*)nil;
Vector u0 = vector_between(position, v0); // relative to origin of model / octree
Vector u1 = vector_between(position, v1);
Vector u0 = HPVectorToVector(HPvector_between(position, v0)); // relative to origin of model / octree
Vector u1 = HPVectorToVector(HPvector_between(position, v1));
Vector w0 = make_vector(dot_product(u0, v_right), dot_product(u0, v_up), dot_product(u0, v_forward)); // in ijk vectors
Vector w1 = make_vector(dot_product(u1, v_right), dot_product(u1, v_up), dot_product(u1, v_forward));
GLfloat hit_distance = [octree isHitByLine:w0 :w1];
@ -4487,10 +4491,10 @@ static GLfloat sBaseMass = 0.0;
ShipEntity *se = nil;
for (subEnum = [self shipSubEntityEnumerator]; (se = [subEnum nextObject]); )
{
Vector p0 = [se absolutePositionForSubentity];
HPVector p0 = [se absolutePositionForSubentity];
Triangle ijk = [se absoluteIJKForSubentity];
u0 = vector_between(p0, v0);
u1 = vector_between(p0, v1);
u0 = HPVectorToVector(HPvector_between(p0, v0));
u1 = HPVectorToVector(HPvector_between(p0, v1));
w0 = resolveVectorInIJK(u0, ijk);
w1 = resolveVectorInIJK(u1, ijk);
@ -4512,7 +4516,7 @@ static GLfloat sBaseMass = 0.0;
- (void) takeEnergyDamage:(double)amount from:(Entity *)ent becauseOf:(Entity *)other
{
Vector rel_pos;
HPVector rel_pos;
double d_forward;
BOOL internal_damage = NO; // base chance
@ -4534,13 +4538,13 @@ static GLfloat sBaseMass = 0.0;
[[ent retain] autorelease];
[[other retain] autorelease];
rel_pos = (ent != nil) ? [ent position] : kZeroVector;
rel_pos = vector_subtract(rel_pos, position);
rel_pos = (ent != nil) ? [ent position] : kZeroHPVector;
rel_pos = HPvector_subtract(rel_pos, position);
[self doScriptEvent:OOJSID("shipBeingAttacked") withArgument:ent];
if ([ent isShip]) [(ShipEntity *)ent doScriptEvent:OOJSID("shipAttackedOther") withArgument:self];
d_forward = dot_product(rel_pos, v_forward);
d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
[self playShieldHit];
@ -4607,7 +4611,7 @@ static GLfloat sBaseMass = 0.0;
- (void) takeScrapeDamage:(double) amount from:(Entity *) ent
{
Vector rel_pos;
HPVector rel_pos;
double d_forward;
BOOL internal_damage = NO; // base chance
@ -4621,9 +4625,10 @@ static GLfloat sBaseMass = 0.0;
OOLog(@"player.ship.damage", @"Player took %.3f scrape damage from %@", amount, ent);
[[ent retain] autorelease];
rel_pos = ent ? [ent position] : kZeroVector;
rel_pos = vector_subtract(rel_pos, position);
d_forward = dot_product(rel_pos, v_forward);
rel_pos = ent ? [ent position] : kZeroHPVector;
rel_pos = HPvector_subtract(rel_pos, position);
// rel_pos is now small
d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
[self playScrapeDamage];
if (d_forward >= 0)
@ -4779,7 +4784,7 @@ static GLfloat sBaseMass = 0.0;
[self adjustVelocity:launchVector];
float sheight = (float)(boundingBox.max.y - boundingBox.min.y);
position = vector_subtract(position, vector_multiply_scalar(v_up, sheight));
position = HPvector_subtract(position, vectorToHPVector(vector_multiply_scalar(v_up, sheight)));
//remove escape pod
[self removeEquipmentItem:@"EQ_ESCAPE_POD"];
@ -5765,9 +5770,9 @@ static GLfloat sBaseMass = 0.0;
- (void) leaveWitchspace
{
float d1 = (float)(SCANNER_MAX_RANGE*((Ranrot() & 255)/256.0 - 0.5));
Vector pos = [UNIVERSE getWitchspaceExitPosition]; // no need to reset the PRNG
HPVector pos = [UNIVERSE getWitchspaceExitPosition]; // no need to reset the PRNG
Quaternion q1;
Vector whpos, exitpos;
HPVector whpos, exitpos;
GLfloat min_d1 = [UNIVERSE safeWitchspaceExitDistance];
quaternion_set_random(&q1);
@ -5775,8 +5780,8 @@ static GLfloat sBaseMass = 0.0;
{
d1 += ((d1 > 0.0)? min_d1: -min_d1); // not too close to the buoy.
}
Vector v1 = vector_forward_from_quaternion(q1);
exitpos = vector_add(pos, vector_multiply_scalar(v1, d1)); // randomise exit position
HPVector v1 = HPvector_forward_from_quaternion(q1);
exitpos = HPvector_add(pos, HPvector_multiply_scalar(v1, d1)); // randomise exit position
position = exitpos;
[self setOrientation:[UNIVERSE getWitchspaceExitRotation]];
@ -5793,25 +5798,25 @@ static GLfloat sBaseMass = 0.0;
if (wh_arrival_time > 0)
{
// Player is following other ship
whpos = vector_add(exitpos, vector_multiply_scalar([self forwardVector], 1000.0f));
whpos = HPvector_add(exitpos, vectorToHPVector(vector_multiply_scalar([self forwardVector], 1000.0f)));
[wormhole setContainsPlayer:YES];
}
else
{
// Player is the leadship
whpos = vector_add(exitpos, vector_multiply_scalar([self forwardVector], -500.0f));
whpos = HPvector_add(exitpos, vectorToHPVector(vector_multiply_scalar([self forwardVector], -500.0f)));
// so it won't contain the player by the time they exit
[wormhole setExitSpeed:maxFlightSpeed*WORMHOLE_LEADER_SPEED_FACTOR];
}
Vector distance = vector_subtract(whpos, pos);
if (magnitude2(distance) < min_d1*min_d1 ) // within safety distance from the buoy?
HPVector distance = HPvector_subtract(whpos, pos);
if (HPmagnitude2(distance) < min_d1*min_d1 ) // within safety distance from the buoy?
{
// the wormhole is to close to the buoy. Move both player and wormhole away from it in the x-y plane.
distance.z = 0;
distance = vector_multiply_scalar(vector_normal(distance), min_d1);
whpos = vector_add(whpos, distance);
position = vector_add(position, distance);
distance = HPvector_multiply_scalar(HPvector_normal(distance), min_d1);
whpos = HPvector_add(whpos, distance);
position = HPvector_add(position, distance);
}
[wormhole setExitPosition: whpos];
}

View File

@ -1520,7 +1520,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
yString = [tokens objectAtIndex:4];
zString = [tokens objectAtIndex:5];
Vector posn = make_vector( [xString floatValue], [yString floatValue], [zString floatValue]);
HPVector posn = make_HPvector( [xString floatValue], [yString floatValue], [zString floatValue]);
int number = [numberString intValue];
if (number < 1)
@ -1562,7 +1562,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
yString = [tokens objectAtIndex:4];
zString = [tokens objectAtIndex:5];
Vector posn = make_vector( [xString floatValue], [yString floatValue], [zString floatValue]);
HPVector posn = make_HPvector( [xString floatValue], [yString floatValue], [zString floatValue]);
int number = [numberString intValue];
if (number < 1)
@ -1597,7 +1597,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
GLfloat y = [[tokens objectAtIndex:4] floatValue];
GLfloat z = [[tokens objectAtIndex:5] floatValue];
GLfloat r = [[tokens objectAtIndex:6] floatValue];
Vector posn = make_vector( x, y, z);
HPVector posn = make_HPvector( x, y, z);
if (number < 1)
{
@ -2260,14 +2260,14 @@ static int scriptRandomSeed = -1; // ensure proper random function
OOLogWARN(@"script.deprecated", @"setting %@ for %@ '%@' in 'abs' inside .plists can cause compatibility issues across Oolite versions. Use coordinates relative to main system objects instead.",@"position",@"planet",planetKey);
}
Vector posn = [UNIVERSE coordinatesFromCoordinateSystemString:positionString];
HPVector posn = [UNIVERSE coordinatesFromCoordinateSystemString:positionString];
if (posn.x || posn.y || posn.z)
{
OOLog(kOOLogDebugAddPlanet, @"planet position (%.2f %.2f %.2f) derived from %@", posn.x, posn.y, posn.z, positionString);
}
else
{
ScanVectorFromString(positionString, &posn);
ScanHPVectorFromString(positionString, &posn);
OOLog(kOOLogDebugAddPlanet, @"planet position (%.2f %.2f %.2f) derived from %@", posn.x, posn.y, posn.z, positionString);
}
[planet setPosition: posn];
@ -2310,14 +2310,14 @@ static int scriptRandomSeed = -1; // ensure proper random function
{
OOLogWARN(@"script.deprecated", @"setting %@ for %@ '%@' in 'abs' inside .plists can cause compatibility issues across Oolite versions. Use coordinates relative to main system objects instead.",@"position",@"moon",moonKey);
}
Vector posn = [UNIVERSE coordinatesFromCoordinateSystemString:positionString];
HPVector posn = [UNIVERSE coordinatesFromCoordinateSystemString:positionString];
if (posn.x || posn.y || posn.z)
{
OOLog(kOOLogDebugAddPlanet, @"moon position (%.2f %.2f %.2f) derived from %@", posn.x, posn.y, posn.z, positionString);
}
else
{
ScanVectorFromString(positionString, &posn);
ScanHPVectorFromString(positionString, &posn);
OOLog(kOOLogDebugAddPlanet, @"moon position (%.2f %.2f %.2f) derived from %@", posn.x, posn.y, posn.z, positionString);
}
[planet setPosition: posn];
@ -2604,7 +2604,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
OOLog(kOOLogDebugProcessSceneStringAddModel, @"::::: adding model to scene:'%@'", ship);
[ship setOrientation: model_q];
[ship setPosition: model_p0];
[ship setPosition: vectorToHPVector(model_p0)];
[UNIVERSE setMainLightPosition:(Vector){ DEMO_LIGHT_POSITION }]; // set light origin
[ship setScanClass: CLASS_NO_DRAW];
[ship switchAITo: @"nullAI.plist"];
@ -2639,7 +2639,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
OOLog(kOOLogDebugProcessSceneStringAddModel, @"::::: adding model to scene:'%@'", doppelganger);
[doppelganger setOrientation: model_q];
[doppelganger setPosition: model_p0];
[doppelganger setPosition: vectorToHPVector(model_p0)];
[UNIVERSE setMainLightPosition:(Vector){ DEMO_LIGHT_POSITION }]; // set light origin
[doppelganger setScanClass: CLASS_NO_DRAW];
[doppelganger switchAITo: @"nullAI.plist"];
@ -2728,7 +2728,8 @@ static int scriptRandomSeed = -1; // ensure proper random function
#endif
OOLog(kOOLogDebugProcessSceneStringAddMiniPlanet, @"::::: adding %@ to scene:'%@'", i_key, doppelganger);
[doppelganger setOrientation: model_q];
[doppelganger setPosition: model_p0];
// HPVect: mission screen coordinates are small enough that we don't need high-precision for calculations
[doppelganger setPosition: vectorToHPVector(model_p0)];
/* MKW - add rotation based on current time
* - necessary to duplicate the rotation already performed in PlanetEntity.m since we reset the orientation above. */
int deltaT = floor(fmod([self clockTimeAdjusted], 86400));

View File

@ -569,6 +569,8 @@ static uint16_t PersonalityForCommanderDict(NSDictionary *dict);
// Remember the savegame target, run js startUp.
[self completeSetUpAndSetTarget:NO];
// run initial system population
[UNIVERSE populateNormalSpace];
[[UNIVERSE gameView] supressKeysUntilKeyUp];
[self setGuiToStatusScreen];

View File

@ -186,7 +186,7 @@ typedef enum
Vector v_forward, v_up, v_right; // unit vectors derived from the direction faced
// variables which are controlled by AI
Vector destination; // for flying to/from a set point
HPVector destination; // for flying to/from a set point
GLfloat desired_range; // range to which to journey/scan
GLfloat desired_speed; // speed at which to travel
@ -304,7 +304,7 @@ typedef enum
// AI stuff
Vector jink; // x and y set factors for offsetting a pursuing ship's position
Vector coordinates; // for flying to/from a set point
HPVector coordinates; // for flying to/from a set point
Vector reference; // a direction vector of magnitude 1 (* turrets *)
NSUInteger _subIdx; // serialisation index - used only if this ship is a subentity
@ -377,7 +377,7 @@ typedef enum
unsigned n_scanned_ships;
// advanced navigation
Vector navpoints[32];
HPVector navpoints[32];
unsigned next_navpoint_index;
unsigned number_of_navpoints;
@ -492,13 +492,13 @@ typedef enum
- (float) volume;
// octree collision hunting
- (GLfloat)doesHitLine:(Vector)v0 :(Vector)v1;
- (GLfloat)doesHitLine:(Vector)v0 :(Vector)v1 :(ShipEntity**)hitEntity;
- (GLfloat)doesHitLine:(Vector)v0 :(Vector)v1 withPosition:(Vector)o andIJK:(Vector)i :(Vector)j :(Vector)k; // for subentities
- (GLfloat)doesHitLine:(HPVector)v0 :(HPVector)v1;
- (GLfloat)doesHitLine:(HPVector)v0 :(HPVector)v1 :(ShipEntity**)hitEntity;
- (GLfloat)doesHitLine:(HPVector)v0 :(HPVector)v1 withPosition:(HPVector)o andIJK:(Vector)i :(Vector)j :(Vector)k; // for subentities
- (BoundingBox) findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector)i :(Vector)j :(Vector)k;
- (BoundingBox) findBoundingBoxRelativeToPosition:(HPVector)opv InVectors:(Vector)i :(Vector)j :(Vector)k;
- (Vector)absoluteTractorPosition;
- (HPVector)absoluteTractorPosition;
// beacons // definitions now in <OOBeaconEntity> protocol
/*- (NSString *) beaconCode;
@ -940,11 +940,11 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (GLfloat) rangeToDestination;
- (double) trackDestination:(double) delta_t :(BOOL) retreat;
- (void) setCoordinate:(Vector)coord;
- (Vector) coordinates;
- (Vector) destination;
- (Vector) distance_six: (GLfloat) dist;
- (Vector) distance_twelve: (GLfloat) dist withOffset:(GLfloat)offset;
- (void) setCoordinate:(HPVector)coord;
- (HPVector) coordinates;
- (HPVector) destination;
- (HPVector) distance_six: (GLfloat) dist;
- (HPVector) distance_twelve: (GLfloat) dist withOffset:(GLfloat)offset;
- (void) setEvasiveJink:(GLfloat) z;
- (void) evasiveAction:(double) delta_t;
@ -1030,8 +1030,8 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (void) switchLightsOff;
- (BOOL) lightsActive;
- (void) setDestination:(Vector) dest;
- (void) setEscortDestination:(Vector) dest;
- (void) setDestination:(HPVector) dest;
- (void) setEscortDestination:(HPVector) dest;
- (BOOL) canAcceptEscort:(ShipEntity *)potentialEscort;
- (BOOL) acceptAsEscort:(ShipEntity *) other_ship;

File diff suppressed because it is too large Load Diff

View File

@ -492,6 +492,15 @@
}
- (void) performBuoyTumble
{
stick_roll = 0.10;
stick_pitch = 0.15;
behaviour = BEHAVIOUR_TUMBLE;
frustration = 0.0;
}
- (void) performStop
{
behaviour = BEHAVIOUR_STOP_STILL;
@ -538,7 +547,7 @@
relativeToEntity:self];
}
distanceToStation2 = distance2([station position], [self position]);
distanceToStation2 = HPdistance2([station position], [self position]);
// Player check for being inside the aegis already exists in PlayerEntityControls. We just
// check here that distance to station is less than 2.5 times scanner range to avoid problems with
@ -577,7 +586,7 @@
{
if (dockingInstructions != nil)
{
destination = [dockingInstructions oo_vectorForKey:@"destination"];
destination = [dockingInstructions oo_hpvectorForKey:@"destination"];
desired_speed = fmin([dockingInstructions oo_floatForKey:@"speed"], maxFlightSpeed);
desired_range = [dockingInstructions oo_floatForKey:@"range"];
if ([dockingInstructions objectForKey:@"station"])
@ -619,7 +628,7 @@
ShipEntity *targEnt = [self primaryTarget];
double found_d2 = scannerRange * scannerRange;
if (targEnt && (distance2(position, [targEnt position]) < found_d2))
if (targEnt && (HPdistance2(position, [targEnt position]) < found_d2))
{
if ([targEnt isWormhole])
whole = (WormholeEntity *)targEnt;
@ -643,7 +652,7 @@
for (i = 0; i < wh_count ; i++)
{
WormholeEntity *wh = wormholes[i];
double d2 = distance2(position, wh->position);
double d2 = HPdistance2(position, wh->position);
if (d2 < found_d2)
{
whole = wh;
@ -852,14 +861,14 @@
- (void) setDestinationToCurrentLocation
{
// randomly add a .5m variance
destination = vector_add(position, OOVectorRandomSpatial(0.5));
destination = HPvector_add(position, OOHPVectorRandomSpatial(0.5));
}
- (void) setDestinationToJinkPosition
{
Vector front = vector_multiply_scalar([self forwardVector], flightSpeed / max_flight_pitch * 2);
destination = vector_add(position, vector_add(front, OOVectorRandomSpatial(100)));
destination = HPvector_add(position, vectorToHPVector(vector_add(front, OOVectorRandomSpatial(100))));
pitching_over = YES; // don't complete roll first, but immediately start with pitching.
}
@ -1145,7 +1154,7 @@
if (!UNIVERSE)
{
Vector vr = vector_multiply_scalar(v_forward, maxFlightSpeed * 10.0); // 10 second flying away
coordinates = vector_add(position, vr);
coordinates = HPvector_add(position, vectorToHPVector(vr));
return;
}
//
@ -1158,15 +1167,15 @@
parameter:nil
relativeToEntity:self];
if (station && distance2([station position], position) < SCANNER_MAX_RANGE2) // there is a station in range.
if (station && HPdistance2([station position], position) < SCANNER_MAX_RANGE2) // there is a station in range.
{
Vector vr = vector_multiply_scalar([station rightVector], 10000); // 10km from station
coordinates = vector_add([station position], vr);
coordinates = HPvector_add([station position], vectorToHPVector(vr));
}
else
{
Vector vr = vector_multiply_scalar(v_forward, maxFlightSpeed * 10.0); // 10 second flying away
coordinates = vector_add(position, vr);
coordinates = HPvector_add(position, vectorToHPVector(vr));
}
}
@ -1270,15 +1279,15 @@
if (the_planet)
{
double variation = (aegis_status == AEGIS_NONE ? 0.5 : 0.2); // more random deviation when far from planet.
Vector p_pos = the_planet->position;
HPVector p_pos = the_planet->position;
double p_cr = the_planet->collision_radius; // the surface
Vector p1 = vector_between(p_pos, position);
p1 = vector_normal(p1); // vector towards ship
HPVector p1 = HPvector_between(p_pos, position);
p1 = HPvector_normal(p1); // vector towards ship
p1.x += variation * (randf() - variation);
p1.y += variation * (randf() - variation);
p1.z += variation * (randf() - variation);
p1 = vector_normal(p1);
destination = vector_add(p_pos, vector_multiply_scalar(p1, p_cr)); // on surface
p1 = HPvector_normal(p1);
destination = HPvector_add(p_pos, HPvector_multiply_scalar(p1, p_cr)); // on surface
desired_range = collision_radius + 100.0; // +100m from the destination
}
else
@ -1294,8 +1303,8 @@
OOPlanetEntity *the_planet = [self findNearestPlanet];
if (the_planet)
{
destination = vector_add([the_planet position], vector_multiply_scalar(
vector_normal(vector_subtract([the_planet position],position)),-10000.0-the_planet->collision_radius));// 10km straight up
destination = HPvector_add([the_planet position], HPvector_multiply_scalar(
HPvector_normal(HPvector_subtract([the_planet position],position)),-10000.0-the_planet->collision_radius));// 10km straight up
desired_range = 50.0;
}
else
@ -1390,11 +1399,11 @@
Entity *the_target = [self primaryTarget];
if (the_target)
{
Vector pos = the_target->position;
HPVector pos = the_target->position;
Quaternion q; quaternion_set_random(&q);
Vector v = vector_forward_from_quaternion(q);
GLfloat d = (randf() - randf()) * the_target->collision_radius;
destination = make_vector(pos.x + d * v.x, pos.y + d * v.y, pos.z + d * v.z);
destination = make_HPvector(pos.x + d * v.x, pos.y + d * v.y, pos.z + d * v.z);
}
}
@ -1403,7 +1412,7 @@
{
Entity *hazard = [UNIVERSE hazardOnRouteFromEntity: self toDistance: desired_range fromPoint: destination];
if (hazard == nil || ([hazard isShip] && distance(position, [hazard position]) > scannerRange) || ([hazard isPlanet] && aegis_status == AEGIS_NONE))
if (hazard == nil || ([hazard isShip] && HPdistance(position, [hazard position]) > scannerRange) || ([hazard isPlanet] && aegis_status == AEGIS_NONE))
[shipAI message:@"COURSE_OK"]; // Avoid going into a waypoint.plist for far away objects, it cripples the main AI a bit in its funtionality.
else
{
@ -1703,7 +1712,7 @@
double maxRange2 = scannerRange * scannerRange;
if (mother && mother != self && magnitude2(vector_subtract(mother->position, position)) < maxRange2)
if (mother && mother != self && HPdistance2(mother->position, position) < maxRange2)
{
[shipAI message:@"TARGET_FOUND"]; // no need for scanning, we still have our mother.
}
@ -1914,47 +1923,47 @@
- (void) setPlanetPatrolCoordinates
{
// check we've arrived near the last given coordinates
Vector r_pos = vector_subtract(position, coordinates);
if (magnitude2(r_pos) < 1000000 || patrol_counter == 0)
HPVector r_pos = HPvector_subtract(position, coordinates);
if (HPmagnitude2(r_pos) < 1000000 || patrol_counter == 0)
{
Entity *the_sun = [UNIVERSE sun];
ShipEntity *the_station = [[self group] leader];
if(!the_station || ![the_station isStation]) the_station = [UNIVERSE station];
if ((!the_sun)||(!the_station))
return;
Vector sun_pos = the_sun->position;
Vector stn_pos = the_station->position;
Vector sun_dir = make_vector(sun_pos.x - stn_pos.x, sun_pos.y - stn_pos.y, sun_pos.z - stn_pos.z);
HPVector sun_pos = the_sun->position;
HPVector stn_pos = the_station->position;
HPVector sun_dir = HPvector_subtract(sun_pos,stn_pos);
Vector vSun = make_vector(0, 0, 1);
if (sun_dir.x||sun_dir.y||sun_dir.z)
vSun = vector_normal(sun_dir);
vSun = HPVectorToVector(HPvector_normal(sun_dir));
Vector v0 = [the_station forwardVector];
Vector v1 = cross_product(v0, vSun);
Vector v2 = cross_product(v0, v1);
switch (patrol_counter)
{
case 0: // first go to 5km ahead of the station
coordinates = make_vector(stn_pos.x + 5000 * v0.x, stn_pos.y + 5000 * v0.y, stn_pos.z + 5000 * v0.z);
coordinates = make_HPvector(stn_pos.x + 5000 * v0.x, stn_pos.y + 5000 * v0.y, stn_pos.z + 5000 * v0.z);
desired_range = 250.0;
break;
case 1: // go to 25km N of the station
coordinates = make_vector(stn_pos.x + 25000 * v1.x, stn_pos.y + 25000 * v1.y, stn_pos.z + 25000 * v1.z);
coordinates = make_HPvector(stn_pos.x + 25000 * v1.x, stn_pos.y + 25000 * v1.y, stn_pos.z + 25000 * v1.z);
desired_range = 250.0;
break;
case 2: // go to 25km E of the station
coordinates = make_vector(stn_pos.x + 25000 * v2.x, stn_pos.y + 25000 * v2.y, stn_pos.z + 25000 * v2.z);
coordinates = make_HPvector(stn_pos.x + 25000 * v2.x, stn_pos.y + 25000 * v2.y, stn_pos.z + 25000 * v2.z);
desired_range = 250.0;
break;
case 3: // go to 25km S of the station
coordinates = make_vector(stn_pos.x - 25000 * v1.x, stn_pos.y - 25000 * v1.y, stn_pos.z - 25000 * v1.z);
coordinates = make_HPvector(stn_pos.x - 25000 * v1.x, stn_pos.y - 25000 * v1.y, stn_pos.z - 25000 * v1.z);
desired_range = 250.0;
break;
case 4: // go to 25km W of the station
coordinates = make_vector(stn_pos.x - 25000 * v2.x, stn_pos.y - 25000 * v2.y, stn_pos.z - 25000 * v2.z);
coordinates = make_HPvector(stn_pos.x - 25000 * v2.x, stn_pos.y - 25000 * v2.y, stn_pos.z - 25000 * v2.z);
desired_range = 250.0;
break;
default: // We should never come here
coordinates = make_vector(stn_pos.x + 5000 * v0.x, stn_pos.y + 5000 * v0.y, stn_pos.z + 5000 * v0.z);
coordinates = make_HPvector(stn_pos.x + 5000 * v0.x, stn_pos.y + 5000 * v0.y, stn_pos.z + 5000 * v0.z);
desired_range = 250.0;
break;
}
@ -1987,9 +1996,9 @@
return;
}
Vector v0 = [UNIVERSE getSunSkimStartPositionForShip:self];
HPVector v0 = [UNIVERSE getSunSkimStartPositionForShip:self];
if (!vector_equal(v0, kZeroVector))
if (!HPvector_equal(v0, kZeroHPVector))
{
coordinates = v0;
[shipAI message:@"APPROACH_COORDINATES"];
@ -2018,11 +2027,11 @@
{
Entity *the_sun = [UNIVERSE sun];
if (the_sun == nil) return;
Vector v1 = [UNIVERSE getSunSkimEndPositionForShip:self];
Vector vs = the_sun->position;
Vector vout = make_vector(v1.x - vs.x, v1.y - vs.y, v1.z - vs.z);
HPVector v1 = [UNIVERSE getSunSkimEndPositionForShip:self];
HPVector vs = the_sun->position;
HPVector vout = HPvector_subtract(v1,vs);
if (vout.x||vout.y||vout.z)
vout = vector_normal(vout);
vout = HPvector_normal(vout);
else
vout.z = 1.0;
v1.x += 10000 * vout.x; v1.y += 10000 * vout.y; v1.z += 10000 * vout.z;
@ -2048,10 +2057,9 @@
[shipAI message:@"NOTHING_FOUND"];
return;
}
Vector v0 = motherStation->position;
Vector rpos = make_vector(position.x - v0.x, position.y - v0.y, position.z - v0.z);
double found_d2 = scannerRange * scannerRange;
if (magnitude2(rpos) > found_d2)
HPVector v0 = motherStation->position;
if (HPdistance2(v0,position) > found_d2)
{
[shipAI message:@"NOTHING_FOUND"];
return;
@ -2122,7 +2130,7 @@
if (oldTarget && ![oldTarget isCloaked])
{
GLfloat range2 = distance2([oldTarget position], position);
GLfloat range2 = HPdistance2([oldTarget position], position);
if (range2 <= scannerRange * scannerRange && range2 <= SCANNER_MAX_RANGE2)
{
found = YES;
@ -2190,11 +2198,11 @@
{
Entity *the_target = [self targetStation];
double bo_distance = 8000; // 8km back off
Vector v0 = position;
Vector d0 = (the_target) ? the_target->position : kZeroVector;
HPVector v0 = position;
HPVector d0 = (the_target) ? the_target->position : kZeroHPVector;
v0.x += (randf() - 0.5)*collision_radius; v0.y += (randf() - 0.5)*collision_radius; v0.z += (randf() - 0.5)*collision_radius;
v0.x -= d0.x; v0.y -= d0.y; v0.z -= d0.z;
v0 = vector_normal_or_fallback(v0, make_vector(0, 0, -1));
v0 = HPvector_normal_or_fallback(v0, make_HPvector(0, 0, -1));
v0.x *= bo_distance; v0.y *= bo_distance; v0.z *= bo_distance;
v0.x += d0.x; v0.y += d0.y; v0.z += d0.z;
@ -2442,7 +2450,7 @@
if ([zString hasPrefix:@"rand:"])
zString = [NSString stringWithFormat:@"%.3f", bellf([(NSString*)[[zString componentsSeparatedByString:@":"] objectAtIndex:1] intValue])];
Vector posn = make_vector([xString floatValue], [yString floatValue], [zString floatValue]);
HPVector posn = make_HPvector([xString floatValue], [yString floatValue], [zString floatValue]);
GLfloat scalar = 1.0;
coordinates = [UNIVERSE coordinatesForPosition:posn withCoordinateSystem:systemString returningScalar:&scalar];
@ -2477,7 +2485,7 @@
if (uni_entities[i]->isStation)
{
my_station = (StationEntity*)uni_entities[i];
if ([my_station maxFlightSpeed] == 0 && [my_station hasNPCTraffic] && distance2(position, [my_station position]) < maxRange2)
if ([my_station maxFlightSpeed] == 0 && [my_station hasNPCTraffic] && HPdistance2(position, [my_station position]) < maxRange2)
{
my_entities[station_count++] = [uni_entities[i] retain]; // retained
}
@ -2691,10 +2699,10 @@
}
Vector k = ship->v_forward;
GLfloat c = ship->collision_radius;
Vector o = ship->position;
navpoints[0] = make_vector(o.x - c * k.x, o.y - c * k.y, o.z - c * k.z);
navpoints[1] = make_vector(o.x + c * k.x, o.y + c * k.y, o.z + c * k.z);
navpoints[2] = make_vector(o.x + 2.0 * c * k.x, o.y + 2.0 * c * k.y, o.z + 2.0 * c * k.z);
HPVector o = ship->position;
navpoints[0] = make_HPvector(o.x - c * k.x, o.y - c * k.y, o.z - c * k.z);
navpoints[1] = make_HPvector(o.x + c * k.x, o.y + c * k.y, o.z + c * k.z);
navpoints[2] = make_HPvector(o.x + 2.0 * c * k.x, o.y + 2.0 * c * k.y, o.z + 2.0 * c * k.z);
number_of_navpoints = 2;
next_navpoint_index = 0;
destination = navpoints[0];

View File

@ -98,9 +98,9 @@ static OOShipGroup *GroupForGroupID(NSUInteger groupID, NSMutableDictionary *con
[result setObject:updatedShipInfo forKey:KEY_SHIPDATA_OVERRIDES];
if (deletes != nil) [result setObject:deletes forKey:KEY_SHIPDATA_DELETES];
if (!vector_equal([self position], kZeroVector))
if (!HPvector_equal([self position], kZeroHPVector))
{
[result oo_setVector:[self position] forKey:KEY_POSITION];
[result oo_setHPVector:[self position] forKey:KEY_POSITION];
}
if (!quaternion_equal([self normalOrientation], kIdentityQuaternion))
{
@ -213,7 +213,7 @@ static OOShipGroup *GroupForGroupID(NSUInteger groupID, NSMutableDictionary *con
}
// The following stuff is deliberately set up the same way even if using role fallback.
[ship setPosition:[dict oo_vectorForKey:KEY_POSITION]];
[ship setPosition:[dict oo_hpvectorForKey:KEY_POSITION]];
[ship setNormalOrientation:[dict oo_quaternionForKey:KEY_ORIENTATION]];
float energyLevel = [dict oo_floatForKey:KEY_ENERGY_LEVEL defaultValue:1.0f];

View File

@ -128,7 +128,7 @@ typedef enum
- (Vector) virtualPortDimensions;
- (DockEntity*) playerReservedDock;
- (Vector) beaconPosition;
- (HPVector) beaconPosition;
- (float) equipmentPriceFactor;
@ -226,4 +226,4 @@ typedef enum
NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, float speed, float range, NSString *ai_message, NSString *comms_message, BOOL match_rotation);
NSDictionary *OOMakeDockingInstructions(StationEntity *station, HPVector coords, float speed, float range, NSString *ai_message, NSString *comms_message, BOOL match_rotation);

View File

@ -99,11 +99,11 @@ MA 02110-1301, USA.
}
- (Vector) beaconPosition
- (HPVector) beaconPosition
{
double buoy_distance = 10000.0; // distance from station entrance
Vector v_f = vector_forward_from_quaternion([self orientation]);
Vector result = vector_add([self position], vector_multiply_scalar(v_f, buoy_distance));
HPVector result = HPvector_add([self position], vectorToHPVector(vector_multiply_scalar(v_f, buoy_distance)));
return result;
}
@ -458,10 +458,10 @@ MA 02110-1301, USA.
}
NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, float speed, float range, NSString *ai_message, NSString *comms_message, BOOL match_rotation)
NSDictionary *OOMakeDockingInstructions(StationEntity *station, HPVector coords, float speed, float range, NSString *ai_message, NSString *comms_message, BOOL match_rotation)
{
NSMutableDictionary *acc = [NSMutableDictionary dictionaryWithCapacity:8];
[acc setObject:[NSString stringWithFormat:@"%.2f %.2f %.2f", coords.x, coords.y, coords.z] forKey:@"destination"];
[acc oo_setHPVector:coords forKey:@"destination"];
[acc oo_setFloat:speed forKey:@"speed"];
[acc oo_setFloat:range forKey:@"range"];
[acc setObject:[[station weakRetain] autorelease] forKey:@"station"];
@ -2415,7 +2415,7 @@ NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, f
unsigned i = 1;
while ((ship = [onHoldEnum nextObject]))
{
OOLog(@"dumpState.stationEntity", @"Nr %i: %@ at distance %g with role: %@", i++, [ship displayName], distance([self position], [ship position]), [ship primaryRole]);
OOLog(@"dumpState.stationEntity", @"Nr %i: %@ at distance %g with role: %@", i++, [ship displayName], HPdistance([self position], [ship position]), [ship primaryRole]);
}
OOLogOutdent();
}

View File

@ -78,7 +78,7 @@ typedef enum
- (BOOL) suckInShip:(ShipEntity *) ship;
- (void) disgorgeShips;
- (void) setExitPosition:(Vector)pos;
- (void) setExitPosition:(HPVector)pos;
- (Random_Seed) origin;
- (Random_Seed) destination;

View File

@ -110,7 +110,7 @@ static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius, int s
// Since this is new for 1.75.1, we must give it a default values as we could be loading an old savegame
estimated_arrival_time = [dict oo_doubleForKey:@"estimated_arrival_time" defaultValue:arrival_time];
position = [dict oo_vectorForKey:@"position"];
position = [dict oo_hpvectorForKey:@"position"];
_misjump = [dict oo_boolForKey:@"misjump" defaultValue:NO];
@ -189,7 +189,7 @@ static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius, int s
expiry_time = arrival_time - 1.0;
}
position = [ship position];
zero_distance = distance2([PLAYER position], position);
zero_distance = HPdistance2([PLAYER position], position);
}
return self;
}
@ -275,7 +275,7 @@ static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius, int s
// MKW 2010.11.18 - calculate time it takes for ship to reach wormhole
// This is for AI ships which get told to enter the wormhole even though they
// may still be some distance from it when the player exits the system
float d = distance(position, [ship position]);
float d = HPdistance(position, [ship position]);
d -= [ship collisionRadius] + [self collisionRadius];
if (d > 0.0f)
{
@ -379,7 +379,7 @@ static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius, int s
if (hasExitPosition && (!containsPlayer || useExitXYScatter))
{
Vector shippos;
HPVector shippos;
Vector exit_vector_x = vector_right_from_quaternion([UNIVERSE getWitchspaceExitRotation]);
Vector exit_vector_y = vector_up_from_quaternion([UNIVERSE getWitchspaceExitRotation]);
// entry wormhole has a radius of around 100m (or perhaps more)
@ -468,7 +468,7 @@ static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius, int s
{
// ships exiting the wormhole after now are following the player
// so appear behind them
position = vector_add([PLAYER position], vector_multiply_scalar([PLAYER forwardVector], -500.0f));
position = HPvector_add([PLAYER position], vectorToHPVector(vector_multiply_scalar([PLAYER forwardVector], -500.0f)));
containsPlayer = NO;
}
// else, the wormhole doesn't now (or never) contained the player, so
@ -482,7 +482,7 @@ static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius, int s
}
- (void) setExitPosition:(Vector)pos
- (void) setExitPosition:(HPVector)pos
{
[self setPosition: pos];
hasExitPosition = YES;
@ -793,7 +793,7 @@ static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius, int s
[myDict oo_setFloat:(expiry_time) forKey:@"expiry_time"];
[myDict oo_setFloat:(arrival_time) forKey:@"arrival_time"];
[myDict oo_setFloat:(estimated_arrival_time) forKey:@"estimated_arrival_time"];
[myDict oo_setVector:position forKey:@"position"];
[myDict oo_setHPVector:position forKey:@"position"];
[myDict oo_setBool:_misjump forKey:@"misjump"];
NSMutableArray * shipArray = [NSMutableArray arrayWithCapacity:[shipsInTransit count]];

View File

@ -1126,7 +1126,7 @@ static void prefetchData(NSDictionary *info, struct CachedInfo *data)
}
ms_blip -= floor(ms_blip);
relativePosition = vector_subtract([scannedEntity position], [PLAYER position]);
relativePosition = [PLAYER vectorTo:scannedEntity];
Vector rp = relativePosition;
if (act_dist > max_zoomed_range)
@ -1357,7 +1357,6 @@ static void prefetchData(NSDictionary *info, struct CachedInfo *data)
alpha = compass_color[3];
// draw the compass
Vector position = [PLAYER position];
OOMatrix rotMatrix = [PLAYER rotationMatrix];
GLfloat h1 = siz.height * 0.125;
@ -1440,7 +1439,8 @@ static void prefetchData(NSDictionary *info, struct CachedInfo *data)
}
// translate and rotate the view
Vector relativePosition = vector_subtract([reference position], position);
Vector relativePosition = [PLAYER vectorTo:reference];
relativePosition = OOVectorMultiplyMatrix(relativePosition, rotMatrix);
relativePosition = vector_normal_or_fallback(relativePosition, kBasisZVector);
@ -2355,7 +2355,6 @@ static OOPolygonSprite *IconForMissileRole(NSString *role)
// draw the direction cue
OOMatrix rotMatrix;
Vector position = [PLAYER position];
rotMatrix = [PLAYER rotationMatrix];
@ -2368,7 +2367,7 @@ static OOPolygonSprite *IconForMissileRole(NSString *role)
const float visMax = 0.984807753012208f; // cos(10 degrees)
// Transform the view
Vector rpn = vector_subtract([target position], position);
Vector rpn = [PLAYER vectorTo:target];
rpn = OOVectorMultiplyMatrix(rpn, rotMatrix);
Vector drawPos = rpn;
Vector forward = kZeroVector;
@ -2538,7 +2537,7 @@ static OOPolygonSprite *IconForMissileRole(NSString *role)
siz.width = useDefined(cached.width, FPSINFO_DISPLAY_WIDTH);
siz.height = useDefined(cached.height, FPSINFO_DISPLAY_HEIGHT);
Vector playerPos = [PLAYER position];
HPVector playerPos = [PLAYER position];
NSString *positionInfo = [UNIVERSE expressPosition:playerPos inCoordinateSystem:@"pwm"];
positionInfo = [NSString stringWithFormat:@"abs %.2f %.2f %.2f / %@", playerPos.x, playerPos.y, playerPos.z, positionInfo];
@ -2929,7 +2928,8 @@ static void hudDrawReticleOnTarget(Entity *target, PlayerEntity *player1, GLfloa
Vector v1 = vector_up_from_quaternion(back_q);
Vector p1;
p1 = vector_subtract([target position], [player1 viewpointPosition]);
// by definition close enough that single precision is fine
p1 = HPVectorToVector(HPvector_subtract([target position], [player1 viewpointPosition]));
GLfloat rdist = magnitude(p1);
GLfloat rsize = [target collisionRadius];

View File

@ -55,6 +55,7 @@ OOINLINE void bounding_box_get_dimensions(BoundingBox bb, GLfloat *xSize, GLfloa
OOINLINE Vector OOBoundingBoxCenter(BoundingBox bb) INLINE_CONST_FUNC;
Vector OORandomPositionInBoundingBox(BoundingBox bb);
HPVector OOHPRandomPositionInBoundingBox(BoundingBox bb);

View File

@ -172,6 +172,7 @@ SOFTWARE.
#ifndef OOCOLLECTIONEXTRACTORS_SIMPLE
- (Vector) oo_vectorForKey:(id)key defaultValue:(Vector)value;
- (HPVector) oo_hpvectorForKey:(id)key defaultValue:(HPVector)value;
- (Quaternion) oo_quaternionForKey:(id)key defaultValue:(Quaternion)value;
#endif
@ -215,6 +216,8 @@ SOFTWARE.
#ifndef OOCOLLECTIONEXTRACTORS_SIMPLE
// Default: kZeroVector
- (Vector) oo_vectorForKey:(id)key;
// Default: kZeroHPVector
- (HPVector) oo_hpvectorForKey:(id)key;
// Default: kIdentityQuaternion
- (Quaternion) oo_quaternionForKey:(id)key;
#endif
@ -327,6 +330,7 @@ SOFTWARE.
- (void) oo_setBool:(BOOL)value forKey:(id)key;
#ifndef OOCOLLECTIONEXTRACTORS_SIMPLE
- (void) oo_setVector:(Vector)value forKey:(id)key;
- (void) oo_setHPVector:(HPVector)value forKey:(id)key;
- (void) oo_setQuaternion:(Quaternion)value forKey:(id)key;
#endif
@ -379,9 +383,11 @@ double OONonNegativeDoubleFromObject(id object, double defaultValue);
#ifndef OOCOLLECTIONEXTRACTORS_SIMPLE
// These take strings, dictionaries or arrays.
Vector OOVectorFromObject(id object, Vector defaultValue);
HPVector OOHPVectorFromObject(id object, HPVector defaultValue);
Quaternion OOQuaternionFromObject(id object, Quaternion defaultValue);
NSDictionary *OOPropertyListFromVector(Vector value);
NSDictionary *OOPropertyListFromHPVector(HPVector value);
NSDictionary *OOPropertyListFromQuaternion(Quaternion value);
#endif

View File

@ -559,6 +559,11 @@ static NSString *StringForObject(id object, NSString *defaultValue);
return OOVectorFromObject([self objectForKey:key], value);
}
- (HPVector) oo_hpvectorForKey:(id)key defaultValue:(HPVector)value
{
return OOHPVectorFromObject([self objectForKey:key], value);
}
- (Quaternion) oo_quaternionForKey:(id)key defaultValue:(Quaternion)value
{
@ -719,6 +724,11 @@ static NSString *StringForObject(id object, NSString *defaultValue);
return [self oo_vectorForKey:key defaultValue:kZeroVector];
}
- (HPVector) oo_hpvectorForKey:(id)key
{
return [self oo_hpvectorForKey:key defaultValue:kZeroHPVector];
}
- (Quaternion) oo_quaternionForKey:(id)key
{
@ -1119,6 +1129,10 @@ static NSString *StringForObject(id object, NSString *defaultValue);
[self setObject:OOPropertyListFromVector(value) forKey:key];
}
- (void) oo_setHPVector:(HPVector)value forKey:(id)key
{
[self setObject:OOPropertyListFromHPVector(value) forKey:key];
}
- (void) oo_setQuaternion:(Quaternion)value forKey:(id)key
{
@ -1411,6 +1425,40 @@ Vector OOVectorFromObject(id object, Vector defaultValue)
return result;
}
HPVector OOHPVectorFromObject(id object, HPVector defaultValue)
{
HPVector result = defaultValue;
NSDictionary *dict = nil;
if ([object isKindOfClass:[NSString class]])
{
// This will only write result if a valid vector is found, and will write an error message otherwise.
ScanHPVectorFromString(object, &result);
}
else if ([object isKindOfClass:[NSArray class]] && [object count] == 3)
{
result.x = [object oo_doubleAtIndex:0];
result.y = [object oo_doubleAtIndex:1];
result.z = [object oo_doubleAtIndex:2];
}
else if ([object isKindOfClass:[NSDictionary class]])
{
dict = object;
// Require at least one of the keys x, y, or z
if ([dict objectForKey:@"x"] != nil ||
[dict objectForKey:@"y"] != nil ||
[dict objectForKey:@"z"] != nil)
{
// Note: uses 0 for unknown components rather than components of defaultValue.
result.x = [dict oo_doubleForKey:@"x" defaultValue:0.0];
result.y = [dict oo_doubleForKey:@"y" defaultValue:0.0];
result.z = [dict oo_doubleForKey:@"z" defaultValue:0.0];
}
}
return result;
}
Quaternion OOQuaternionFromObject(id object, Quaternion defaultValue)
{
@ -1459,6 +1507,15 @@ NSDictionary *OOPropertyListFromVector(Vector value)
nil];
}
NSDictionary *OOPropertyListFromHPVector(HPVector value)
{
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:value.x], @"x",
[NSNumber numberWithDouble:value.y], @"y",
[NSNumber numberWithDouble:value.z], @"z",
nil];
}
NSDictionary *OOPropertyListFromQuaternion(Quaternion value)
{

357
src/Core/OOHPVector.h Normal file
View File

@ -0,0 +1,357 @@
/*
OOHPVector.h
Mathematical framework for Oolite.
High-precision vectors for world-space coordinates
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#ifndef INCLUDED_OOMATHS_h
#error Do not include OOHPVector.h directly; include OOMaths.h.
#else
#ifndef OOMATHS_EXTERNAL_VECTOR_TYPES
typedef struct HPVector
{
OOHPScalar x;
OOHPScalar y;
OOHPScalar z;
} HPVector;
typedef struct HPVector2D
{
OOHPScalar x;
OOHPScalar y;
} HPVector2D;
#endif
extern const HPVector kZeroHPVector, /* 0, 0, 0 */
kBasisXHPVector, /* 1, 0, 0 */
kBasisYHPVector, /* 0, 1, 0 */
kBasisZHPVector; /* 0, 0, 1 */
extern const HPVector2D kZeroHPVector2D, /* 0, 0 */
kBasisXHPVector2D, /* 1, 0 */
kBasisYHPVector2D; /* 0, 1 */
/* Construct vector */
OOINLINE HPVector make_HPvector(OOHPScalar vx, OOHPScalar vy, OOHPScalar vz) INLINE_CONST_FUNC;
OOINLINE HPVector2D MakeHPVector2D(OOHPScalar vx, OOHPScalar vy) INLINE_CONST_FUNC;
OOINLINE HPVector vectorToHPVector(Vector v) INLINE_CONST_FUNC;
OOINLINE Vector HPVectorToVector(HPVector v) INLINE_CONST_FUNC;
#if !OOMATHS_STANDALONE
/* Generate random vectors. */
HPVector OORandomUnitHPVector(void);
HPVector OOHPVectorRandomSpatial(OOHPScalar maxLength); // Random vector uniformly distributed in radius-maxLength sphere. (Longer vectors are more common.)
HPVector OOHPVectorRandomRadial(OOHPScalar maxLength); // Random vector with uniform distribution of direction and radius in radius-maxLength sphere. (Causes clustering at centre.)
HPVector OORandomPositionInCylinder(HPVector centre1, OOHPScalar exclusion1, HPVector centre2, OOHPScalar exclusion2, OOHPScalar radius);
HPVector OORandomPositionInShell(HPVector centre, OOHPScalar inner, OOHPScalar outer);
/* returns the projection of 'point' to the plane defined by the point
'plane' and the normal vector 'normal' */
HPVector OOProjectHPVectorToPlane(HPVector point, HPVector plane, HPVector normal);
#endif
/* Multiply vector by scalar (in place) */
OOINLINE void HPscale_vector(HPVector *outHPVector, OOHPScalar factor) ALWAYS_INLINE_FUNC NONNULL_FUNC;
/* Multiply vector by scalar */
OOINLINE HPVector HPvector_multiply_scalar(HPVector v, OOHPScalar s) INLINE_CONST_FUNC;
/* Addition and subtraction of vectors */
OOINLINE HPVector HPvector_add(HPVector a, HPVector b) INLINE_CONST_FUNC;
OOINLINE HPVector HPvector_subtract(HPVector a, HPVector b) INLINE_CONST_FUNC;
#define HPvector_between(a, b) HPvector_subtract(b, a)
OOINLINE HPVector HPvector_flip(HPVector v) INLINE_CONST_FUNC;
/* HPVector linear interpolation */
OOINLINE HPVector OOHPVectorInterpolate(HPVector a, HPVector b, OOHPScalar where) INLINE_CONST_FUNC;
OOINLINE HPVector OOHPVectorTowards(HPVector a, HPVector b, OOHPScalar where) INLINE_CONST_FUNC;
/* Comparison of vectors */
OOINLINE bool HPvector_equal(HPVector a, HPVector b) INLINE_CONST_FUNC;
/* Square of magnitude of vector */
OOINLINE OOHPScalar HPmagnitude2(HPVector vec) INLINE_CONST_FUNC;
/* Magnitude of vector */
OOINLINE OOHPScalar HPmagnitude(HPVector vec) INLINE_CONST_FUNC;
/* Normalize vector */
OOINLINE HPVector HPvector_normal(HPVector vec) INLINE_CONST_FUNC;
/* Normalize vector, returning fallback if zero vector. */
OOINLINE HPVector HPvector_normal_or_fallback(HPVector vec, HPVector fallback) INLINE_CONST_FUNC;
OOINLINE HPVector HPvector_normal_or_xbasis(HPVector vec) INLINE_CONST_FUNC;
OOINLINE HPVector HPvector_normal_or_ybasis(HPVector vec) INLINE_CONST_FUNC;
OOINLINE HPVector HPvector_normal_or_zbasis(HPVector vec) INLINE_CONST_FUNC;
/* Square of distance between vectors */
OOINLINE OOHPScalar HPdistance2(HPVector v1, HPVector v2) INLINE_CONST_FUNC;
/* Distance between vectors */
OOINLINE OOHPScalar HPdistance(HPVector v1, HPVector v2) INLINE_CONST_FUNC;
/* Dot product */
OOINLINE OOHPScalar HPdot_product (HPVector first, HPVector second) INLINE_CONST_FUNC;
/* NORMALIZED cross product */
OOINLINE HPVector HPcross_product(HPVector first, HPVector second) INLINE_CONST_FUNC;
/* General cross product */
OOINLINE HPVector HPtrue_cross_product(HPVector first, HPVector second) CONST_FUNC;
/* Triple product */
OOINLINE OOHPScalar HPtriple_product(HPVector first, HPVector second, HPVector third) INLINE_CONST_FUNC;
/* Given three points on a surface, returns the normal to the surface. */
OOINLINE HPVector HPnormal_to_surface(HPVector v1, HPVector v2, HPVector v3) CONST_FUNC;
#if __OBJC__
NSString *HPVectorDescription(HPVector vector); // @"(x, y, z)"
#endif
#if OOMATHS_OPENGL_INTEGRATION
/* OpenGL conveniences. Need to be macros to work with OOMacroOpenGL. */
#define GLVertexOOHPVector(v) do { HPVector v_ = v; glVertex3f(v_.x, v_.y, v_.z); } while (0)
#define GLTranslateOOHPVector(v) do { HPVector v_ = v; OOGL(glTranslatef(v_.x, v_.y, v_.z)); } while (0)
#endif
/*** Only inline definitions beyond this point ***/
OOINLINE HPVector make_HPvector (OOHPScalar vx, OOHPScalar vy, OOHPScalar vz)
{
HPVector result;
result.x = vx;
result.y = vy;
result.z = vz;
return result;
}
OOINLINE HPVector2D MakeHPVector2D(OOHPScalar vx, OOHPScalar vy)
{
HPVector2D result;
result.x = vx;
result.y = vy;
return result;
}
OOINLINE HPVector vectorToHPVector(Vector v) {
HPVector result;
result.x = (OOHPScalar)v.x;
result.y = (OOHPScalar)v.y;
result.z = (OOHPScalar)v.z;
return result;
}
OOINLINE Vector HPVectorToVector(HPVector v) {
Vector result;
result.x = (OOScalar)v.x;
result.y = (OOScalar)v.y;
result.z = (OOScalar)v.z;
return result;
}
OOINLINE void HPscale_vector(HPVector *vec, OOHPScalar factor)
{
/*
Clang static analyzer: reports an unintialized value here when called
from -[HeadUpDisplay rescaleByFactor:]. This is blatantly wrong, as
the array the vector comes from is fully initialized in the range being
looped over.
-- Ahruman 2012-09-14
*/
vec->x *= factor;
vec->y *= factor;
vec->z *= factor;
}
OOINLINE HPVector HPvector_multiply_scalar(HPVector v, OOHPScalar s)
{
/*
Clang static analyzer: reports a garbage value here when called from
-[OOMesh rescaleByFactor:], apparently on baseless assumption that
OOMesh._vertices points to only one vertex.
-- Ahruman 2012-09-14
*/
HPVector r;
r.x = v.x * s;
r.y = v.y * s;
r.z = v.z * s;
return r;
}
OOINLINE HPVector HPvector_add(HPVector a, HPVector b)
{
HPVector r;
r.x = a.x + b.x;
r.y = a.y + b.y;
r.z = a.z + b.z;
return r;
}
OOINLINE HPVector OOHPVectorInterpolate(HPVector a, HPVector b, OOHPScalar where)
{
return make_HPvector(OOLerp(a.x, b.x, where),
OOLerp(a.y, b.y, where),
OOLerp(a.z, b.z, where));
}
OOINLINE HPVector OOHPVectorTowards(HPVector a, HPVector b, OOHPScalar where)
{
return make_HPvector(a.x + b.x * where,
a.y + b.y * where,
a.z + b.z * where);
}
OOINLINE HPVector HPvector_subtract(HPVector a, HPVector b)
{
HPVector r;
r.x = a.x - b.x;
r.y = a.y - b.y;
r.z = a.z - b.z;
return r;
}
OOINLINE HPVector HPvector_flip(HPVector v)
{
return HPvector_subtract(kZeroHPVector, v);
}
OOINLINE bool HPvector_equal(HPVector a, HPVector b)
{
return a.x == b.x && a.y == b.y && a.z == b.z;
}
OOINLINE OOHPScalar HPmagnitude2(HPVector vec)
{
return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z;
}
OOINLINE OOHPScalar HPmagnitude(HPVector vec)
{
return sqrt(HPmagnitude2(vec));
}
OOINLINE HPVector HPvector_normal_or_fallback(HPVector vec, HPVector fallback)
{
OOHPScalar mag2 = HPmagnitude2(vec);
if (EXPECT_NOT(mag2 == 0.0f)) return fallback;
return HPvector_multiply_scalar(vec, 1.0f / sqrt(mag2));
}
OOINLINE HPVector HPvector_normal_or_xbasis(HPVector vec)
{
return HPvector_normal_or_fallback(vec, kBasisXHPVector);
}
OOINLINE HPVector HPvector_normal_or_ybasis(HPVector vec)
{
return HPvector_normal_or_fallback(vec, kBasisYHPVector);
}
OOINLINE HPVector HPvector_normal_or_zbasis(HPVector vec)
{
return HPvector_normal_or_fallback(vec, kBasisZHPVector);
}
OOINLINE HPVector HPvector_normal(HPVector vec)
{
return HPvector_normal_or_fallback(vec, kZeroHPVector);
}
OOINLINE OOHPScalar HPdistance2(HPVector v1, HPVector v2)
{
return HPmagnitude2(HPvector_subtract(v1, v2));
}
OOINLINE OOHPScalar HPdistance(HPVector v1, HPVector v2)
{
return HPmagnitude(HPvector_subtract(v1, v2));
}
OOINLINE HPVector HPtrue_cross_product(HPVector first, HPVector second)
{
HPVector result;
result.x = (first.y * second.z) - (first.z * second.y);
result.y = (first.z * second.x) - (first.x * second.z);
result.z = (first.x * second.y) - (first.y * second.x);
return result;
}
OOINLINE HPVector HPcross_product(HPVector first, HPVector second)
{
return HPvector_normal(HPtrue_cross_product(first, second));
}
OOINLINE OOHPScalar HPdot_product (HPVector a, HPVector b)
{
return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
}
OOINLINE OOHPScalar HPtriple_product(HPVector first, HPVector second, HPVector third)
{
return HPdot_product(first, HPtrue_cross_product(second, third));
}
OOINLINE HPVector HPnormal_to_surface(HPVector v1, HPVector v2, HPVector v3)
{
HPVector d0, d1;
d0 = HPvector_subtract(v2, v1);
d1 = HPvector_subtract(v3, v2);
return HPcross_product(d0, d1);
}
#endif /* INCLUDED_OOMATHS_h */

137
src/Core/OOHPVector.m Normal file
View File

@ -0,0 +1,137 @@
/*
OOHPVector.m
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#include "OOMaths.h"
const HPVector kZeroHPVector = { 0.0f, 0.0f, 0.0f };
const HPVector kBasisXHPVector = { 1.0f, 0.0f, 0.0f };
const HPVector kBasisYHPVector = { 0.0f, 1.0f, 0.0f };
const HPVector kBasisZHPVector = { 0.0f, 0.0f, 1.0f };
const HPVector2D kZeroHPVector2D = { 0.0f, 0.0f };
const HPVector2D kBasisXHPVector2D = { 1.0f, 0.0f };
const HPVector2D kBasisYHPVector2D = { 0.0f, 1.0f };
/*#if !OOMATHS_STANDALONE
const BoundingBox kZeroBoundingBox = {{ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }};
#endif*/
#if __OBJC__
NSString *HPVectorDescription(HPVector vector)
{
return [NSString stringWithFormat:@"(%g, %g, %g)", vector.x, vector.y, vector.z];
}
#endif
#if !OOMATHS_STANDALONE
/* This generates random vectors distrubuted evenly over the surface of the
unit sphere. It does this the simple way, by generating vectors in the
half-unit cube and rejecting those outside the half-unit sphere (and the
zero vector), then normalizing the result. (Half-unit measures are used
to avoid unnecessary multiplications of randf() values.)
In principle, using three normally-distributed co-ordinates (and again
normalizing the result) would provide the right result without looping, but
I don't trust bellf() so I'll go with the simple approach for now.
*/
HPVector OORandomUnitHPVector(void)
{
HPVector v;
OOHPScalar m;
do
{
v = make_HPvector(randf() - 0.5f, randf() - 0.5f, randf() - 0.5f);
m = HPmagnitude2(v);
}
while (m > 0.25f || m == 0.0f); // We're confining to a sphere of radius 0.5 using the sqared magnitude; 0.5 squared is 0.25.
return HPvector_normal(v);
}
HPVector OOHPVectorRandomSpatial(OOHPScalar maxLength)
{
HPVector v;
OOHPScalar m;
do
{
v = make_HPvector(randf() - 0.5f, randf() - 0.5f, randf() - 0.5f);
m = HPmagnitude2(v);
}
while (m > 0.25f); // We're confining to a sphere of radius 0.5 using the sqared magnitude; 0.5 squared is 0.25.
return HPvector_multiply_scalar(v, maxLength * 2.0f); // 2.0 is to compensate for the 0.5-radius sphere.
}
HPVector OOHPVectorRandomRadial(OOHPScalar maxLength)
{
return HPvector_multiply_scalar(OORandomUnitHPVector(), randf() * maxLength);
}
HPVector OOHPRandomPositionInBoundingBox(BoundingBox bb)
{
HPVector result;
result.x = (OOHPScalar)(bb.min.x + randf() * (bb.max.x - bb.min.x));
result.y = (OOHPScalar)(bb.min.y + randf() * (bb.max.y - bb.min.y));
result.z = (OOHPScalar)(bb.min.z + randf() * (bb.max.z - bb.min.z));
return result;
}
HPVector OORandomPositionInCylinder(HPVector centre1, OOHPScalar exclusion1, HPVector centre2, OOHPScalar exclusion2, OOHPScalar radius)
{
OOHPScalar exc12 = exclusion1*exclusion1;
OOHPScalar exc22 = exclusion2*exclusion2;
HPVector result;
do
{
result = HPvector_add(OOHPVectorInterpolate(centre1,centre2,randf()),OOHPVectorRandomSpatial(radius));
}
while(HPdistance2(result,centre1)<exc12 || HPdistance2(result,centre2)<exc22);
return result;
}
HPVector OORandomPositionInShell(HPVector centre, OOHPScalar inner, OOHPScalar outer)
{
HPVector result;
OOHPScalar inner2 = inner*inner;
do
{
result = HPvector_add(centre,OOHPVectorRandomSpatial(outer));
} while(HPdistance2(result,centre)<inner2);
return result;
}
HPVector OOProjectHPVectorToPlane(HPVector point, HPVector plane, HPVector normal)
{
return HPvector_subtract(point,HPvector_multiply_scalar(normal,HPdot_product(HPvector_subtract(point, plane), normal)));
}
#endif

View File

@ -66,6 +66,8 @@ typedef GLfloat OOScalar;
typedef float OOScalar;
#endif
typedef double OOHPScalar;
#ifndef M_PI
#define M_PI 3.14159265358979323846 /* pi */
@ -119,6 +121,7 @@ typedef float OOScalar;
#include "OOFastArithmetic.h"
#include "OOVector.h"
#include "OOHPVector.h"
#include "OOQuaternion.h"
#include "OOMatrix.h"

View File

@ -62,11 +62,12 @@ OOMatrix OOMatrixForQuaternionRotation(Quaternion orientation);
OOINLINE OOMatrix OOMatrixForTranslation(Vector v) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixForTranslationComponents(OOScalar dx, OOScalar dy, OOScalar dz) INLINE_CONST_FUNC;
OOMatrix OOMatrixForBillboard(Vector bbPos, Vector eyePos) CONST_FUNC;
OOMatrix OOMatrixForBillboard(HPVector bbPos, HPVector eyePos) CONST_FUNC;
/* Matrix transformations */
OOINLINE OOMatrix OOMatrixTranslate(OOMatrix m, Vector offset) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixHPTranslate(OOMatrix m, HPVector offset) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixTranslateComponents(OOMatrix m, OOScalar dx, OOScalar dy, OOScalar dz) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixScale(OOMatrix m, OOScalar sx, OOScalar sy, OOScalar sz) INLINE_CONST_FUNC;
@ -86,6 +87,7 @@ OOINLINE bool OOMatrixIsIdentity(OOMatrix m) INLINE_CONST_FUNC;
/* Matrix multiplication */
OOMatrix OOMatrixMultiply(OOMatrix a, OOMatrix b) CONST_FUNC;
Vector OOVectorMultiplyMatrix(Vector v, OOMatrix m) CONST_FUNC;
HPVector OOHPVectorMultiplyMatrix(HPVector v, OOMatrix m) CONST_FUNC;
/* Extraction */
@ -239,6 +241,11 @@ OOINLINE OOMatrix OOMatrixTranslate(OOMatrix m, Vector offset)
return OOMatrixTranslateComponents(m, offset.x, offset.y, offset.z);
}
OOINLINE OOMatrix OOMatrixHPTranslate(OOMatrix m, HPVector offset)
{
return OOMatrixTranslateComponents(m, (OOScalar)offset.x, (OOScalar)offset.y, (OOScalar)offset.z);
}
OOINLINE OOMatrix OOMatrixForScale(OOScalar sx, OOScalar sy, OOScalar sz)
{

View File

@ -137,6 +137,22 @@ Vector OOVectorMultiplyMatrix(Vector v, OOMatrix m)
return make_vector(x * w, y * w, z * w);
}
// HPVect: this loses precision because the matrix is single-precision
// Best used for rotation matrices only - use HPvector_add for
// translations of vectors if possible
HPVector OOHPVectorMultiplyMatrix(HPVector v, OOMatrix m)
{
OOScalar x, y, z, w;
x = m.m[0][0] * v.x + m.m[1][0] * v.y + m.m[2][0] * v.z + m.m[3][0];
y = m.m[0][1] * v.x + m.m[1][1] * v.y + m.m[2][1] * v.z + m.m[3][1];
z = m.m[0][2] * v.x + m.m[1][2] * v.y + m.m[2][2] * v.z + m.m[3][2];
w = m.m[0][3] * v.x + m.m[1][3] * v.y + m.m[2][3] * v.z + m.m[3][3];
w = 1.0f/w;
return make_HPvector(x * w, y * w, z * w);
}
OOMatrix OOMatrixOrthogonalize(OOMatrix m)
{
@ -170,11 +186,13 @@ NSString *OOMatrixDescription(OOMatrix matrix)
#endif
OOMatrix OOMatrixForBillboard(Vector bbPos, Vector eyePos)
OOMatrix OOMatrixForBillboard(HPVector bbPos, HPVector eyePos)
{
Vector v0, v1, v2, arbv;
v0 = vector_subtract(bbPos, eyePos);
v0 = HPVectorToVector(HPvector_subtract(bbPos, eyePos));
// once the subtraction is done safe to lose precision since
// we're now dealing with relatively small vectors
v0 = vector_normal_or_fallback(v0, kBasisZVector);
// arbitrary axis - not aligned with v0

View File

@ -75,6 +75,8 @@ Vector vector_forward_from_quaternion(Quaternion quat) CONST_FUNC;
Vector vector_up_from_quaternion(Quaternion quat) CONST_FUNC;
Vector vector_right_from_quaternion(Quaternion quat) CONST_FUNC;
HPVector HPvector_forward_from_quaternion(Quaternion quat) CONST_FUNC;
void basis_vectors_from_quaternion(Quaternion quat, Vector *outRight, Vector *outUp, Vector *outForward);
/* produce a quaternion representing an angle between two vectors. Assumes the vectors are normalized. */
@ -98,6 +100,7 @@ NSString *QuaternionDescription(Quaternion quaternion); // @"(w + xi + yj + zk)"
Vector quaternion_rotate_vector(Quaternion q, Vector vector) CONST_FUNC;
HPVector quaternion_rotate_HPvector(Quaternion q, HPVector vector) CONST_FUNC;

View File

@ -80,6 +80,11 @@ Vector vector_forward_from_quaternion(Quaternion quat)
else return make_vector(0.0f, 0.0f, 1.0f);
}
HPVector HPvector_forward_from_quaternion(Quaternion quat)
{
// HPVect: profile this later
return vectorToHPVector(vector_forward_from_quaternion(quat));
}
Vector vector_up_from_quaternion(Quaternion quat)
{
@ -361,3 +366,19 @@ Vector quaternion_rotate_vector(Quaternion q, Vector v)
return v;
}
HPVector quaternion_rotate_HPvector(Quaternion q, HPVector v)
{
Quaternion qv;
qv.w = 0.0f - q.x * v.x - q.y * v.y - q.z * v.z;
qv.x = -q.w * v.x + q.y * v.z - q.z * v.y;
qv.y = -q.w * v.y + q.z * v.x - q.x * v.z;
qv.z = -q.w * v.z + q.x * v.y - q.y * v.x;
v.x = qv.w * -q.x + qv.x * -q.w + qv.y * -q.z - qv.z * -q.y;
v.y = qv.w * -q.y + qv.y * -q.w + qv.z * -q.x - qv.x * -q.z;
v.z = qv.w * -q.z + qv.z * -q.w + qv.x * -q.y - qv.y * -q.x;
return v;
}

View File

@ -36,6 +36,7 @@ NSMutableArray *ScanTokensFromString(NSString *values);
// Note: these functions will leave their out values untouched if they fail (and return NO). They will not log an error if passed a NULL string (but will return NO). This means they can be used to, say, read dictionary entries which might not exist. They also ignore any extra components in the string.
BOOL ScanVectorFromString(NSString *xyzString, Vector *outVector);
BOOL ScanHPVectorFromString(NSString *xyzString, HPVector *outVector);
BOOL ScanQuaternionFromString(NSString *wxyzString, Quaternion *outQuaternion);
BOOL ScanVectorAndQuaternionFromString(NSString *xyzwxyzString, Vector *outVector, Quaternion *outQuaternion);

View File

@ -105,6 +105,18 @@ BOOL ScanVectorFromString(NSString *xyzString, Vector *outVector)
}
}
BOOL ScanHPVectorFromString(NSString *xyzString, HPVector *outVector)
{
Vector scanVector;
assert(outVector != NULL);
BOOL result = ScanVectorFromString(xyzString, &scanVector);
if (!result)
{
return NO;
}
*outVector = vectorToHPVector(scanVector);
return YES;
}
BOOL ScanQuaternionFromString(NSString *wxyzString, Quaternion *outQuaternion)
{

View File

@ -69,6 +69,9 @@ OOINLINE Vector2D MakeVector2D(OOScalar vx, OOScalar vy) INLINE_CONST_FUNC;
Vector OORandomUnitVector(void);
Vector OOVectorRandomSpatial(OOScalar maxLength); // Random vector uniformly distributed in radius-maxLength sphere. (Longer vectors are more common.)
Vector OOVectorRandomRadial(OOScalar maxLength); // Random vector with uniform distribution of direction and radius in radius-maxLength sphere. (Causes clustering at centre.)
// only needed in high-precision forms so far
//Vector OORandomPositionInCylinder(Vector centre1, OOScalar exclusion1, Vector centre2, OOScalar exclusion2, OOScalar radius);
//Vector OORandomPositionInShell(Vector centre, OOScalar inner, OOScalar outer);
#endif
/* Multiply vector by scalar (in place) */

View File

@ -104,4 +104,30 @@ Vector OORandomPositionInBoundingBox(BoundingBox bb)
result.z = bb.min.z + randf() * (bb.max.z - bb.min.z);
return result;
}
// only need high precision versions of these
/*Vector OORandomPositionInCylinder(Vector centre1, OOScalar exclusion1, Vector centre2, OOScalar exclusion2, OOScalar radius)
{
OOScalar exc12 = exclusion1*exclusion1;
OOScalar exc22 = exclusion2*exclusion2;
Vector result;
do
{
result = vector_add(OOVectorInterpolate(centre1,centre2,randf()),OOVectorRandomSpatial(radius));
}
while(distance2(result,centre1)<exc12 || distance2(result,centre2)<exc22);
return result;
}
Vector OORandomPositionInShell(Vector centre, OOScalar inner, OOScalar outer)
{
Vector result;
OOScalar inner2 = inner*inner;
do
{
result = vector_add(centre,OOVectorRandomSpatial(outer));
} while(distance2(result,centre)<inner2);
return result;
}*/
#endif

View File

@ -206,7 +206,7 @@ static JSBool EntityGetProperty(JSContext *context, JSObject *this, jsid propID,
return JS_NewNumberValue(context, [entity collisionRadius], value);
case kEntity_position:
return VectorToJSValue(context, [entity position], value);
return HPVectorToJSValue(context, [entity position], value);
case kEntity_orientation:
return QuaternionToJSValue(context, [entity normalOrientation], value);
@ -321,7 +321,7 @@ static JSBool EntitySetProperty(JSContext *context, JSObject *this, jsid propID,
Entity *entity = nil;
double fValue;
Vector vValue;
HPVector hpvValue;
Quaternion qValue;
if (EXPECT_NOT(!OOJSEntityGetEntity(context, this, &entity))) return NO;
@ -330,9 +330,9 @@ static JSBool EntitySetProperty(JSContext *context, JSObject *this, jsid propID,
switch (JSID_TO_INT(propID))
{
case kEntity_position:
if (JSValueToVector(context, *value, &vValue))
if (JSValueToHPVector(context, *value, &hpvValue))
{
[entity setPosition:vValue];
[entity setPosition:hpvValue];
if ([entity isShip])
{
[(ShipEntity *)entity resetExhaustPlumes];

View File

@ -0,0 +1,46 @@
/*
OOJSPopulatorDefinition.h
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOJSScript.h"
#include <jsapi.h>
#import "OOMaths.h"
@interface OOJSPopulatorDefinition: OOWeakRefObject
{
@private
jsval _callback;
JSObject *_callbackThis;
OOJSScript *_owningScript;
}
- (jsval)callback;
- (void)setCallback:(jsval)callback;
- (JSObject *)callbackThis;
- (void)setCallbackThis:(JSObject *)callbackthis;
- (void)runCallback:(HPVector)location;
@end

View File

@ -0,0 +1,128 @@
/*
OOJSPopulatorDefinition.m
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOJSPopulatorDefinition.h"
#import "OOJavaScriptEngine.h"
#import "OOMaths.h"
#import "OOJSVector.h"
@implementation OOJSPopulatorDefinition
- (id) init {
_callback = JSVAL_VOID;
_callbackThis = NULL;
_owningScript = [[OOJSScript currentlyRunningScript] weakRetain];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deleteJSPointers)
name:kOOJavaScriptEngineWillResetNotification
object:[OOJavaScriptEngine sharedEngine]];
return self;
}
- (void) deleteJSPointers
{
JSContext *context = OOJSAcquireContext();
_callback = JSVAL_VOID;
_callbackThis = NULL;
JS_RemoveValueRoot(context, &_callback);
JS_RemoveObjectRoot(context, &_callbackThis);
OOJSRelinquishContext(context);
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kOOJavaScriptEngineWillResetNotification
object:[OOJavaScriptEngine sharedEngine]];
}
- (void) dealloc
{
[_owningScript release];
[self deleteJSPointers];
[super dealloc];
}
- (jsval)callback
{
return _callback;
}
- (void)setCallback:(jsval)callback
{
JSContext *context = OOJSAcquireContext();
JS_RemoveValueRoot(context, &_callback);
_callback = callback;
OOJSAddGCValueRoot(context, &_callback, "OOJSPopulatorDefinition callback function");
OOJSRelinquishContext(context);
}
- (JSObject *)callbackThis
{
return _callbackThis;
}
- (void)setCallbackThis:(JSObject *)callbackThis
{
JSContext *context = OOJSAcquireContext();
JS_RemoveObjectRoot(context, &_callbackThis);
_callbackThis = callbackThis;
OOJSAddGCObjectRoot(context, &_callbackThis, "OOJSPopulatorDefinition callback this");
OOJSRelinquishContext(context);
}
- (void)runCallback:(HPVector)location
{
OOJavaScriptEngine *engine = [OOJavaScriptEngine sharedEngine];
JSContext *context = OOJSAcquireContext();
jsval loc, rval = JSVAL_VOID;
VectorToJSValue(context, HPVectorToVector(location), &loc);
OOJSScript *owner = [_owningScript retain]; // local copy needed
[OOJSScript pushScript:owner];
[engine callJSFunction:_callback
forObject:_callbackThis
argc:1
argv:&loc
result:&rval];
[OOJSScript popScript:owner];
[owner release];
OOJSRelinquishContext(context);
}
@end

View File

@ -38,3 +38,4 @@ MA 02110-1301, USA.
#define OOJSID(str) ({ static jsid idCache = JSID_VOID; if (EXPECT_NOT(idCache == JSID_VOID)) OOJSInitJSIDCachePRIVATE(""str, &idCache); idCache; })
#endif
void OOJSInitJSIDCachePRIVATE(const char *name, jsid *idCache);

View File

@ -652,7 +652,7 @@ static JSBool QuaternionRotate(JSContext *context, uintN argc, jsval *vp)
OOJS_PROFILE_ENTER
Quaternion thisq;
Vector axis;
HPVector axis;
double angle;
uintN consumed;
jsval *argv = OOJS_ARGV;
@ -664,7 +664,7 @@ static JSBool QuaternionRotate(JSContext *context, uintN argc, jsval *vp)
if (argc > 0)
{
if (EXPECT_NOT(!OOJSArgumentListGetNumber(context, @"Quaternion", @"rotate", argc, argv, &angle, NULL))) return NO;
quaternion_rotate_about_axis(&thisq, axis, angle);
quaternion_rotate_about_axis(&thisq, HPVectorToVector(axis), angle);
}
// Else no angle specified, so don't rotate and pass value through unchanged.

View File

@ -731,7 +731,7 @@ static JSBool ShipGetProperty(JSContext *context, JSObject *this, jsid propID, j
return JS_NewNumberValue(context, [entity desiredSpeed], value);
case kShip_destination:
return VectorToJSValue(context, [entity destination], value);
return HPVectorToJSValue(context, [entity destination], value);
case kShip_maxEscorts:
return JS_NewNumberValue(context, [entity maxEscortCount], value);
@ -840,7 +840,7 @@ static JSBool ShipGetProperty(JSContext *context, JSObject *this, jsid propID, j
return JS_NewNumberValue(context, [entity missileLoadTime], value);
case kShip_savedCoordinates:
return VectorToJSValue(context, [entity coordinates], value);
return HPVectorToJSValue(context,[entity coordinates], value);
case kShip_equipment:
result = [entity equipmentListForScripting];
@ -985,6 +985,7 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsid propID, J
int32 iValue;
JSBool bValue;
Vector vValue;
HPVector hpvValue;
OOShipGroup *group = nil;
OOColor *colorForScript = nil;
BOOL exists;
@ -1221,11 +1222,11 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsid propID, J
case kShip_destination:
if (EXPECT_NOT([entity isPlayer])) goto playerReadOnly;
if (JSValueToVector(context, *value, &vValue))
if (JSValueToHPVector(context, *value, &hpvValue))
{
// use setEscortDestination rather than setDestination as
// scripted amendments shouldn't necessarily reset frustration
[entity setEscortDestination:vValue];
[entity setEscortDestination:hpvValue];
return YES;
}
break;
@ -1251,9 +1252,9 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsid propID, J
break;
case kShip_savedCoordinates:
if (JSValueToVector(context, *value, &vValue))
if (JSValueToHPVector(context, *value, &hpvValue))
{
[entity setCoordinate:vValue];
[entity setCoordinate:hpvValue];
return YES;
}
break;

View File

@ -39,7 +39,7 @@
#import "OOConstToJSString.h"
#import "OOEntityFilterPredicate.h"
#import "OOFilteringEnumerator.h"
#import "OOJSPopulatorDefinition.h"
static JSObject *sSystemPrototype;
@ -74,6 +74,7 @@ static JSBool SystemAddGroup(JSContext *context, uintN argc, jsval *vp);
static JSBool SystemAddShipsToRoute(JSContext *context, uintN argc, jsval *vp);
static JSBool SystemAddGroupToRoute(JSContext *context, uintN argc, jsval *vp);
static JSBool SystemAddVisualEffect(JSContext *context, uintN argc, jsval *vp);
static JSBool SystemSetPopulator(JSContext *context, uintN argc, jsval *vp);
static JSBool SystemLegacyAddShips(JSContext *context, uintN argc, jsval *vp);
static JSBool SystemLegacyAddSystemShips(JSContext *context, uintN argc, jsval *vp);
@ -123,6 +124,7 @@ enum
kSystem_name, // name, string, read/write
kSystem_planets, // planets in system, array of Planet, read-only
kSystem_population, // population, integer, read/write
kSystem_populatorSettings, // populator settings, dictionary, read-only
kSystem_productivity, // productivity, integer, read/write
kSystem_pseudoRandom100, // constant-per-system pseudorandom number in [0..100), integer, read-only
kSystem_pseudoRandom256, // constant-per-system pseudorandom number in [0..256), integer, read-only
@ -152,6 +154,7 @@ static JSPropertySpec sSystemProperties[] =
{ "name", kSystem_name, OOJS_PROP_READWRITE_CB },
{ "planets", kSystem_planets, OOJS_PROP_READONLY_CB },
{ "population", kSystem_population, OOJS_PROP_READWRITE_CB },
{ "populatorSettings", kSystem_populatorSettings, OOJS_PROP_READONLY_CB },
{ "productivity", kSystem_productivity, OOJS_PROP_READWRITE_CB },
{ "pseudoRandom100", kSystem_pseudoRandom100, OOJS_PROP_READONLY_CB },
{ "pseudoRandom256", kSystem_pseudoRandom256, OOJS_PROP_READONLY_CB },
@ -180,6 +183,7 @@ static JSFunctionSpec sSystemMethods[] =
{ "filteredEntities", SystemFilteredEntities, 2 },
// scrambledPseudoRandomNumber is implemented in oolite-global-prefix.js
{ "sendAllShipsAway", SystemSendAllShipsAway, 1 },
{ "setPopulator", SystemSetPopulator, 2 },
{ "shipsWithPrimaryRole", SystemShipsWithPrimaryRole, 1 },
{ "shipsWithRole", SystemShipsWithRole, 1 },
@ -287,6 +291,10 @@ static JSBool SystemGetProperty(JSContext *context, JSObject *this, jsid propID,
case kSystem_breakPattern:
*value = OOJSValueFromBOOL([UNIVERSE witchspaceBreakPattern]);
return YES;
case kSystem_populatorSettings:
*value = OOJSValueFromNativeObject(context, [UNIVERSE getPopulatorSettings]);
return YES;
}
if (!handled)
@ -934,7 +942,7 @@ static JSBool SystemLegacyAddShipsAt(JSContext *context, uintN argc, jsval *vp)
OOJS_NATIVE_ENTER(context)
PlayerEntity *player = OOPlayerForScripting();
Vector where;
HPVector where;
NSString *role = nil;
int32 count;
NSString *coordScheme = nil;
@ -970,7 +978,7 @@ static JSBool SystemLegacyAddShipsAtPrecisely(JSContext *context, uintN argc, js
OOJS_NATIVE_ENTER(context)
PlayerEntity *player = OOPlayerForScripting();
Vector where;
HPVector where;
NSString *role = nil;
int32 count;
NSString *coordScheme = nil;
@ -1006,7 +1014,7 @@ static JSBool SystemLegacyAddShipsWithinRadius(JSContext *context, uintN argc, j
OOJS_NATIVE_ENTER(context)
PlayerEntity *player = OOPlayerForScripting();
Vector where;
HPVector where;
jsdouble radius;
NSString *role = nil;
int32 count;
@ -1152,7 +1160,7 @@ static JSBool SystemAddVisualEffect(JSContext *context, uintN argc, jsval *vp)
OOJS_NATIVE_ENTER(context)
NSString *key = nil;
Vector where;
HPVector where;
uintN consumed = 0;
@ -1182,6 +1190,72 @@ static JSBool SystemAddVisualEffect(JSContext *context, uintN argc, jsval *vp)
OOJS_NATIVE_EXIT
}
static JSBool SystemSetPopulator(JSContext *context, uintN argc, jsval *vp)
{
OOJS_NATIVE_ENTER(context)
NSString *key;
NSMutableDictionary *settings;
JSObject *params = NULL;
if (argc < 1)
{
OOJSReportBadArguments(context, @"System", @"setPopulator", MIN(argc, 0U), &OOJS_ARGV[0], nil, @"string (key), object (settings)");
return NO;
}
key = OOStringFromJSValue(context, OOJS_ARGV[0]);
if (key == nil)
{
OOJSReportBadArguments(context, @"System", @"setPopulator", MIN(argc, 0U), &OOJS_ARGV[0], nil, @"key, settings");
return NO;
}
if (argc < 2)
{
// clearing
[UNIVERSE setPopulatorSetting:key to:nil];
}
else
{
// adding
if (!JS_ValueToObject(context, OOJS_ARGV[1], &params))
{
OOJSReportBadArguments(context, @"System", @"setPopulator", MIN(argc, 1U), OOJS_ARGV, NULL, @"key, settings");
return NO;
}
jsval callback = JSVAL_NULL;
if (JS_GetProperty(context, params, "callback", &callback) == JS_FALSE || JSVAL_IS_VOID(callback))
{
OOJSReportBadArguments(context, @"System", @"setPopulator", MIN(argc, 1U), OOJS_ARGV, NULL, @"settings must have a 'callback' property.");
return NO;
}
OOJSPopulatorDefinition *populator = [[OOJSPopulatorDefinition alloc] init];
[populator setCallback:callback];
settings = OOJSNativeObjectFromJSObject(context, JSVAL_TO_OBJECT(OOJS_ARGV[1]));
[settings setObject:populator forKey:@"callbackObj"];
jsval coords = JSVAL_NULL;
if (JS_GetProperty(context, params, "coordinates", &coords) != JS_FALSE && !JSVAL_IS_VOID(coords))
{
Vector coordinates = kZeroVector;
if (JSValueToVector(context, coords, &coordinates))
{
// convert vector in NS-storable form
[settings setObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:coordinates.x],[NSNumber numberWithFloat:coordinates.y],[NSNumber numberWithFloat:coordinates.z],nil] forKey:@"coordinates"];
}
}
[populator release];
[UNIVERSE setPopulatorSetting:key to:settings];
}
OOJS_RETURN_VOID;
OOJS_NATIVE_EXIT
}
// *** Helper functions ***
// Shared implementation of addShips() and addGroup().
@ -1192,7 +1266,7 @@ static JSBool SystemAddShipsOrGroup(JSContext *context, uintN argc, jsval *vp, B
NSString *role = nil;
int32 count = 0;
uintN consumed = 0;
Vector where;
HPVector where;
double radius = NSNotFound; // a negative value means
id result = nil;
@ -1405,8 +1479,8 @@ static NSComparisonResult CompareEntitiesByDistance(id a, id b, void *relativeTo
*r = (id)relativeTo;
float d1, d2;
d1 = distance2(ea->position, r->position);
d2 = distance2(eb->position, r->position);
d1 = HPdistance2(ea->position, r->position);
d2 = HPdistance2(eb->position, r->position);
if (d1 < d2) return NSOrderedAscending;
else if (d1 > d2) return NSOrderedDescending;

View File

@ -33,20 +33,24 @@ void InitOOJSVector(JSContext *context, JSObject *global);
JSObject *JSVectorWithVector(JSContext *context, Vector vector) NONNULL_FUNC;
JSObject *JSVectorWithHPVector(JSContext *context, HPVector vector) NONNULL_FUNC;
BOOL VectorToJSValue(JSContext *context, Vector vector, jsval *outValue) NONNULL_FUNC;
BOOL HPVectorToJSValue(JSContext *context, HPVector vector, jsval *outValue) NONNULL_FUNC;
BOOL NSPointToVectorJSValue(JSContext *context, NSPoint point, jsval *outValue) NONNULL_FUNC;
BOOL JSValueToVector(JSContext *context, jsval value, Vector *outVector) NONNULL_FUNC;
BOOL JSValueToHPVector(JSContext *context, jsval value, HPVector *outVector) NONNULL_FUNC;
/* Given a JS Vector object, get the corresponding Vector struct. Given a JS
Entity, get its position. Given a JS Array with exactly three elements,
all of them numbers, treat them as [x, y, z] components. For anything
else, return NO. (Other implicit conversions may be added in future.)
*/
BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVector) GCC_ATTR((nonnull (1, 3)));
BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, HPVector *outVector) GCC_ATTR((nonnull (1, 3)));
// Set the value of a JS vector object.
BOOL JSVectorSetVector(JSContext *context, JSObject *vectorObj, Vector vector) GCC_ATTR((nonnull (1)));
BOOL JSVectorSetHPVector(JSContext *context, JSObject *vectorObj, HPVector vector) GCC_ATTR((nonnull (1)));
/* VectorFromArgumentList()
@ -62,10 +66,10 @@ BOOL JSVectorSetVector(JSContext *context, JSObject *vectorObj, Vector vector)
DEPRECATED in favour of JSObjectGetVector(), since the list-of-number form
is no longer used.
*/
BOOL VectorFromArgumentList(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, Vector *outVector, uintN *outConsumed) GCC_ATTR((nonnull (1, 5, 6)));
BOOL VectorFromArgumentList(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed) GCC_ATTR((nonnull (1, 5, 6)));
/* VectorFromArgumentListNoError()
Like VectorFromArgumentList(), but does not report an error on failure.
*/
BOOL VectorFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv, Vector *outVector, uintN *outConsumed) GCC_ATTR((nonnull (1, 3, 4)));
BOOL VectorFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed) GCC_ATTR((nonnull (1, 3, 4)));

View File

@ -39,7 +39,7 @@ MA 02110-1301, USA.
static JSObject *sVectorPrototype;
static BOOL GetThisVector(JSContext *context, JSObject *vectorObj, Vector *outVector, NSString *method) NONNULL_FUNC;
static BOOL GetThisVector(JSContext *context, JSObject *vectorObj, HPVector *outVector, NSString *method) NONNULL_FUNC;
static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
@ -161,12 +161,12 @@ JSObject *JSVectorWithVector(JSContext *context, Vector vector)
OOJS_PROFILE_ENTER
JSObject *result = NULL;
Vector *private = NULL;
HPVector *private = NULL;
private = malloc(sizeof *private);
if (EXPECT_NOT(private == NULL)) return NULL;
*private = vector;
*private = vectorToHPVector(vector);
result = JS_NewObject(context, &sVectorClass, sVectorPrototype, NULL);
if (result != NULL)
@ -199,6 +199,49 @@ BOOL VectorToJSValue(JSContext *context, Vector vector, jsval *outValue)
OOJS_PROFILE_EXIT
}
JSObject *JSVectorWithHPVector(JSContext *context, HPVector vector)
{
OOJS_PROFILE_ENTER
JSObject *result = NULL;
HPVector *private = NULL;
private = malloc(sizeof *private);
if (EXPECT_NOT(private == NULL)) return NULL;
*private = vector;
result = JS_NewObject(context, &sVectorClass, sVectorPrototype, NULL);
if (result != NULL)
{
if (EXPECT_NOT(!JS_SetPrivate(context, result, private))) result = NULL;
}
if (EXPECT_NOT(result == NULL)) free(private);
return result;
OOJS_PROFILE_EXIT
}
BOOL HPVectorToJSValue(JSContext *context, HPVector vector, jsval *outValue)
{
OOJS_PROFILE_ENTER
JSObject *object = NULL;
assert(outValue != NULL);
object = JSVectorWithHPVector(context, vector);
if (EXPECT_NOT(object == NULL)) return NO;
*outValue = OBJECT_TO_JSVAL(object);
return YES;
OOJS_PROFILE_EXIT
}
BOOL NSPointToVectorJSValue(JSContext *context, NSPoint point, jsval *outValue)
{
@ -206,13 +249,22 @@ BOOL NSPointToVectorJSValue(JSContext *context, NSPoint point, jsval *outValue)
}
BOOL JSValueToVector(JSContext *context, jsval value, Vector *outVector)
BOOL JSValueToHPVector(JSContext *context, jsval value, HPVector *outVector)
{
if (EXPECT_NOT(!JSVAL_IS_OBJECT(value))) return NO;
return JSObjectGetVector(context, JSVAL_TO_OBJECT(value), outVector);
}
BOOL JSValueToVector(JSContext *context, jsval value, Vector *outVector)
{
if (EXPECT_NOT(!JSVAL_IS_OBJECT(value))) return NO;
HPVector tmp = kZeroHPVector;
BOOL result = JSObjectGetVector(context, JSVAL_TO_OBJECT(value), &tmp);
*outVector = HPVectorToVector(tmp);
return result;
}
#if OO_DEBUG
@ -275,13 +327,13 @@ static VectorStatistics sVectorConversionStats;
#endif
BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVector)
BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, HPVector *outVector)
{
OOJS_PROFILE_ENTER
assert(outVector != NULL);
Vector *private = NULL;
HPVector *private = NULL;
jsuint arrayLength;
jsval arrayX, arrayY, arrayZ;
jsdouble x, y, z;
@ -318,7 +370,7 @@ BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVecto
JS_ValueToNumber(context, arrayZ, &z))
{
COUNT(arrayCount);
*outVector = make_vector(x, y, z);
*outVector = make_HPvector(x, y, z);
return YES;
}
}
@ -344,7 +396,7 @@ BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVecto
if (JS_InstanceOf(context, vectorObj, &sVectorClass, NULL))
{
COUNT(protoCount);
*outVector = kZeroVector;
*outVector = kZeroHPVector;
return YES;
}
@ -355,7 +407,7 @@ BOOL JSObjectGetVector(JSContext *context, JSObject *vectorObj, Vector *outVecto
}
static BOOL GetThisVector(JSContext *context, JSObject *vectorObj, Vector *outVector, NSString *method)
static BOOL GetThisVector(JSContext *context, JSObject *vectorObj, HPVector *outVector, NSString *method)
{
if (EXPECT(JSObjectGetVector(context, vectorObj, outVector))) return YES;
@ -366,10 +418,16 @@ static BOOL GetThisVector(JSContext *context, JSObject *vectorObj, Vector *outVe
BOOL JSVectorSetVector(JSContext *context, JSObject *vectorObj, Vector vector)
{
return JSVectorSetHPVector(context,vectorObj,vectorToHPVector(vector));
}
BOOL JSVectorSetHPVector(JSContext *context, JSObject *vectorObj, HPVector vector)
{
OOJS_PROFILE_ENTER
Vector *private = NULL;
HPVector *private = NULL;
if (EXPECT_NOT(vectorObj == NULL)) return NO;
@ -392,7 +450,7 @@ BOOL JSVectorSetVector(JSContext *context, JSObject *vectorObj, Vector vector)
}
static BOOL VectorFromArgumentListNoErrorInternal(JSContext *context, uintN argc, jsval *argv, Vector *outVector, uintN *outConsumed, BOOL permitNumberList)
static BOOL VectorFromArgumentListNoErrorInternal(JSContext *context, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed, BOOL permitNumberList)
{
OOJS_PROFILE_ENTER
@ -424,7 +482,7 @@ static BOOL VectorFromArgumentListNoErrorInternal(JSContext *context, uintN argc
if (EXPECT_NOT(!JS_ValueToNumber(context, argv[2], &z) || isnan(z))) return NO;
// We got our three numbers.
*outVector = make_vector(x, y, z);
*outVector = make_HPvector(x, y, z);
if (outConsumed != NULL) *outConsumed = 3;
return YES;
@ -434,7 +492,7 @@ static BOOL VectorFromArgumentListNoErrorInternal(JSContext *context, uintN argc
// EMMSTRAN: remove outConsumed, since it can only be 1 except in failure (constructor is an exception, but it uses VectorFromArgumentListNoErrorInternal() directly).
BOOL VectorFromArgumentList(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, Vector *outVector, uintN *outConsumed)
BOOL VectorFromArgumentList(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed)
{
if (VectorFromArgumentListNoErrorInternal(context, argc, argv, outVector, outConsumed, NO)) return YES;
else
@ -447,7 +505,7 @@ BOOL VectorFromArgumentList(JSContext *context, NSString *scriptClass, NSString
}
BOOL VectorFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv, Vector *outVector, uintN *outConsumed)
BOOL VectorFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv, HPVector *outVector, uintN *outConsumed)
{
return VectorFromArgumentListNoErrorInternal(context, argc, argv, outVector, outConsumed, NO);
}
@ -461,8 +519,8 @@ static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsid propID,
OOJS_PROFILE_ENTER
Vector vector;
GLfloat fValue;
HPVector vector;
OOHPScalar fValue;
if (EXPECT_NOT(!JSObjectGetVector(context, this, &vector))) return NO;
@ -497,7 +555,7 @@ static JSBool VectorSetProperty(JSContext *context, JSObject *this, jsid propID,
OOJS_PROFILE_ENTER
Vector vector;
HPVector vector;
jsdouble dval;
if (EXPECT_NOT(!JSObjectGetVector(context, this, &vector))) return NO;
@ -526,7 +584,7 @@ static JSBool VectorSetProperty(JSContext *context, JSObject *this, jsid propID,
return NO;
}
return JSVectorSetVector(context, this, vector);
return JSVectorSetHPVector(context, this, vector);
OOJS_PROFILE_EXIT
}
@ -552,8 +610,8 @@ static JSBool VectorConstruct(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector vector = kZeroVector;
Vector *private = NULL;
HPVector vector = kZeroHPVector;
HPVector *private = NULL;
JSObject *this = NULL;
private = malloc(sizeof *private);
@ -595,11 +653,11 @@ static JSBool VectorToString(JSContext *context, uintN argc, jsval *vp)
{
OOJS_NATIVE_ENTER(context)
Vector thisv;
HPVector thisv;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"toString"))) return NO;
OOJS_RETURN_OBJECT(VectorDescription(thisv));
OOJS_RETURN_OBJECT(HPVectorDescription(thisv));
OOJS_NATIVE_EXIT
}
@ -610,7 +668,7 @@ static JSBool VectorToSource(JSContext *context, uintN argc, jsval *vp)
{
OOJS_NATIVE_ENTER(context)
Vector thisv;
HPVector thisv;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"toSource"))) return NO;
@ -626,14 +684,14 @@ static JSBool VectorAdd(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv, result;
HPVector thisv, thatv, result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"add"))) return NO;
if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"add", argc, OOJS_ARGV, &thatv, NULL))) return NO;
result = vector_add(thisv, thatv);
result = HPvector_add(thisv, thatv);
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
OOJS_PROFILE_EXIT
}
@ -644,14 +702,14 @@ static JSBool VectorSubtract(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv, result;
HPVector thisv, thatv, result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"subtract"))) return NO;
if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"subtract", argc, OOJS_ARGV, &thatv, NULL))) return NO;
result = vector_subtract(thisv, thatv);
result = HPvector_subtract(thisv, thatv);
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
OOJS_PROFILE_EXIT
}
@ -662,13 +720,13 @@ static JSBool VectorDistanceTo(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
HPVector thisv, thatv;
GLfloat result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"distanceTo"))) return NO;
if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"distanceTo", argc, OOJS_ARGV, &thatv, NULL))) return NO;
result = distance(thisv, thatv);
result = HPdistance(thisv, thatv);
OOJS_RETURN_DOUBLE(result);
@ -681,13 +739,13 @@ static JSBool VectorSquaredDistanceTo(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
HPVector thisv, thatv;
GLfloat result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"squaredDistanceTo"))) return NO;
if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"squaredDistanceTo", argc, OOJS_ARGV, &thatv, NULL))) return NO;
result = distance2(thisv, thatv);
result = HPdistance2(thisv, thatv);
OOJS_RETURN_DOUBLE(result);
@ -700,15 +758,15 @@ static JSBool VectorMultiply(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, result;
HPVector thisv, result;
double scalar;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"multiply"))) return NO;
if (EXPECT_NOT(!OOJSArgumentListGetNumber(context, @"Vector3D", @"multiply", argc, OOJS_ARGV, &scalar, NULL))) return NO;
result = vector_multiply_scalar(thisv, scalar);
result = HPvector_multiply_scalar(thisv, scalar);
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
OOJS_PROFILE_EXIT
}
@ -719,13 +777,13 @@ static JSBool VectorDot(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
HPVector thisv, thatv;
GLfloat result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"dot"))) return NO;
if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"dot", argc, OOJS_ARGV, &thatv, NULL))) return NO;
result = dot_product(thisv, thatv);
result = HPdot_product(thisv, thatv);
OOJS_RETURN_DOUBLE(result);
@ -738,13 +796,13 @@ static JSBool VectorAngleTo(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
HPVector thisv, thatv;
GLfloat result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"angleTo"))) return NO;
if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"angleTo", argc, OOJS_ARGV, &thatv, NULL))) return NO;
result = dot_product(vector_normal(thisv), vector_normal(thatv));
result = HPdot_product(HPvector_normal(thisv), HPvector_normal(thatv));
if (result > 1.0f) result = 1.0f;
if (result < -1.0f) result = -1.0f;
// for identical vectors the dot_product sometimes returnes a value > 1.0 because of rounding errors, resulting
@ -762,14 +820,14 @@ static JSBool VectorCross(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv, result;
HPVector thisv, thatv, result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"cross"))) return NO;
if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"cross", argc, OOJS_ARGV, &thatv, NULL))) return NO;
result = true_cross_product(thisv, thatv);
result = HPtrue_cross_product(thisv, thatv);
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
OOJS_PROFILE_EXIT
}
@ -780,7 +838,7 @@ static JSBool VectorTripleProduct(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv, theotherv;
HPVector thisv, thatv, theotherv;
GLfloat result;
uintN consumed;
jsval *argv = OOJS_ARGV;
@ -791,7 +849,7 @@ static JSBool VectorTripleProduct(JSContext *context, uintN argc, jsval *vp)
argv += consumed;
if (EXPECT_NOT(!VectorFromArgumentList(context, @"Vector3D", @"tripleProduct", argc, argv, &theotherv, NULL))) return NO;
result = triple_product(thisv, thatv, theotherv);
result = HPtriple_product(thisv, thatv, theotherv);
OOJS_RETURN_DOUBLE(result);
@ -804,13 +862,13 @@ static JSBool VectorDirection(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, result;
HPVector thisv, result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"direction"))) return NO;
result = vector_normal(thisv);
result = HPvector_normal(thisv);
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
OOJS_PROFILE_EXIT
}
@ -821,12 +879,12 @@ static JSBool VectorMagnitude(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv;
HPVector thisv;
GLfloat result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"magnitude"))) return NO;
result = magnitude(thisv);
result = HPmagnitude(thisv);
OOJS_RETURN_DOUBLE(result);
@ -839,12 +897,12 @@ static JSBool VectorSquaredMagnitude(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv;
HPVector thisv;
GLfloat result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"squaredMagnitude"))) return NO;
result = magnitude2(thisv);
result = HPmagnitude2(thisv);
OOJS_RETURN_DOUBLE(result);
@ -857,7 +915,7 @@ static JSBool VectorRotationTo(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
HPVector thisv, thatv;
double limit;
BOOL gotLimit;
Quaternion result;
@ -876,8 +934,8 @@ static JSBool VectorRotationTo(JSContext *context, uintN argc, jsval *vp)
}
else gotLimit = NO;
if (gotLimit) result = quaternion_limited_rotation_between(thisv, thatv, limit);
else result = quaternion_rotation_between(thisv, thatv);
if (gotLimit) result = quaternion_limited_rotation_between(HPVectorToVector(thisv), HPVectorToVector(thatv), limit);
else result = quaternion_rotation_between(HPVectorToVector(thisv), HPVectorToVector(thatv));
OOJS_RETURN_QUATERNION(result);
@ -890,15 +948,15 @@ static JSBool VectorRotateBy(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv, result;
HPVector thisv, result;
Quaternion q;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"rotateBy"))) return NO;
if (EXPECT_NOT(!QuaternionFromArgumentList(context, @"Vector3D", @"rotateBy", argc, OOJS_ARGV, &q, NULL))) return NO;
result = quaternion_rotate_vector(q, thisv);
result = quaternion_rotate_HPvector(q, thisv);
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
OOJS_PROFILE_EXIT
}
@ -909,7 +967,7 @@ static JSBool VectorToArray(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector thisv;
HPVector thisv;
JSObject *result = NULL;
jsval nVal;
@ -942,9 +1000,9 @@ static JSBool VectorToCoordinateSystem(JSContext *context, uintN argc, jsval *vp
{
OOJS_NATIVE_ENTER(context)
Vector thisv;
HPVector thisv;
NSString *coordScheme = nil;
Vector result;
HPVector result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"toCoordinateSystem"))) return NO;
@ -959,7 +1017,7 @@ static JSBool VectorToCoordinateSystem(JSContext *context, uintN argc, jsval *vp
result = [UNIVERSE legacyPositionFrom:thisv asCoordinateSystem:coordScheme];
OOJS_END_FULL_NATIVE
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
OOJS_NATIVE_EXIT
}
@ -970,9 +1028,9 @@ static JSBool VectorFromCoordinateSystem(JSContext *context, uintN argc, jsval *
{
OOJS_NATIVE_ENTER(context)
Vector thisv;
HPVector thisv;
NSString *coordScheme = nil;
Vector result;
HPVector result;
if (EXPECT_NOT(!GetThisVector(context, OOJS_THIS, &thisv, @"fromCoordinateSystem"))) return NO;
@ -988,7 +1046,7 @@ static JSBool VectorFromCoordinateSystem(JSContext *context, uintN argc, jsval *
result = [UNIVERSE coordinatesFromCoordinateSystemString:arg];
OOJS_END_FULL_NATIVE
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
OOJS_NATIVE_EXIT
}
@ -1002,9 +1060,9 @@ static JSBool VectorStaticInterpolate(JSContext *context, uintN argc, jsval *vp)
{
OOJS_PROFILE_ENTER
Vector av, bv;
HPVector av, bv;
double interp;
Vector result;
HPVector result;
uintN consumed;
uintN inArgc = argc;
jsval *argv = OOJS_ARGV;
@ -1021,9 +1079,9 @@ static JSBool VectorStaticInterpolate(JSContext *context, uintN argc, jsval *vp)
if (EXPECT_NOT(argc < 1)) goto INSUFFICIENT_ARGUMENTS;
if (EXPECT_NOT(!OOJSArgumentListGetNumber(context, @"Vector3D", @"interpolate", argc, argv, &interp, NULL))) return NO;
result = OOVectorInterpolate(av, bv, interp);
result = OOHPVectorInterpolate(av, bv, interp);
OOJS_RETURN_VECTOR(result);
OOJS_RETURN_HPVECTOR(result);
INSUFFICIENT_ARGUMENTS:
OOJSReportBadArguments(context, @"Vector3D", @"interpolate", inArgc, inArgv,
@ -1044,7 +1102,7 @@ static JSBool VectorStaticRandom(JSContext *context, uintN argc, jsval *vp)
if (argc == 0 || !OOJSArgumentListGetNumberNoError(context, argc, OOJS_ARGV, &maxLength, NULL)) maxLength = 1.0;
OOJS_RETURN_VECTOR(OOVectorRandomSpatial(maxLength));
OOJS_RETURN_HPVECTOR(OOHPVectorRandomSpatial(maxLength));
OOJS_PROFILE_EXIT
}
@ -1059,7 +1117,7 @@ static JSBool VectorStaticRandomDirection(JSContext *context, uintN argc, jsval
if (argc == 0 || !OOJSArgumentListGetNumberNoError(context, argc, OOJS_ARGV, &scale, NULL)) scale = 1.0;
OOJS_RETURN_VECTOR(vector_multiply_scalar(OORandomUnitVector(), scale));
OOJS_RETURN_HPVECTOR(HPvector_multiply_scalar(OORandomUnitHPVector(), scale));
OOJS_PROFILE_EXIT
}
@ -1074,7 +1132,7 @@ static JSBool VectorStaticRandomDirectionAndLength(JSContext *context, uintN arg
if (argc == 0 || !OOJSArgumentListGetNumberNoError(context, argc, OOJS_ARGV, &maxLength, NULL)) maxLength = 1.0;
OOJS_RETURN_VECTOR(OOVectorRandomRadial(maxLength));
OOJS_RETURN_HPVECTOR(OOHPVectorRandomRadial(maxLength));
OOJS_PROFILE_EXIT
}

View File

@ -675,5 +675,6 @@ do { \
} while (0)
#define OOJS_RETURN_VECTOR(value) OOJS_RETURN_WITH_HELPER(VectorToJSValue, value)
#define OOJS_RETURN_HPVECTOR(value) OOJS_RETURN_WITH_HELPER(HPVectorToJSValue, value)
#define OOJS_RETURN_QUATERNION(value) OOJS_RETURN_WITH_HELPER(QuaternionToJSValue, value)
#define OOJS_RETURN_DOUBLE(value) OOJS_RETURN_WITH_HELPER(JS_NewNumberValue, value)

View File

@ -145,6 +145,8 @@ enum
#define MIN_DISTANCE_TO_BUOY 750.0f // don't add ships within this distance
#define MIN_DISTANCE_TO_BUOY2 (MIN_DISTANCE_TO_BUOY * MIN_DISTANCE_TO_BUOY)
#define SYSTEM_REPOPULATION_INTERVAL 20.0f;
#ifndef OO_LOCALIZATION_TOOLS
#define OO_LOCALIZATION_TOOLS 1
#endif
@ -257,6 +259,10 @@ enum
OOSunEntity *cachedSun;
NSMutableArray *allPlanets;
NSMutableDictionary *populatorSettings;
OOTimeDelta next_repopulation;
NSString *system_repopulator;
NSArray *closeSystems;
BOOL strict;
@ -339,6 +345,11 @@ enum
- (void) setUpWitchspace;
- (void) setUpWitchspaceBetweenSystem:(Random_Seed)s1 andSystem:(Random_Seed)s2;
- (void) setUpSpace;
- (void) populateNormalSpace;
- (void) clearSystemPopulator;
- (void) populateSystemFromDictionariesWithSun:(OOSunEntity *)sun andPlanet:(OOPlanetEntity *)planet;
- (NSDictionary *) getPopulatorSettings;
- (void) setPopulatorSetting:(NSString *)key to:(NSDictionary *)setting;
- (void) setLighting;
- (void) forceLightSwitch;
- (void) setMainLightPosition: (Vector) sunPos;
@ -346,22 +357,22 @@ enum
- (void) makeSunSkimmer:(ShipEntity *) ship andSetAI:(BOOL)setAI;
- (void) addShipWithRole:(NSString *) desc nearRouteOneAt:(double) route_fraction;
- (Vector) coordinatesForPosition:(Vector) pos withCoordinateSystem:(NSString *) system returningScalar:(GLfloat*) my_scalar;
- (NSString *) expressPosition:(Vector) pos inCoordinateSystem:(NSString *) system;
- (Vector) legacyPositionFrom:(Vector) pos asCoordinateSystem:(NSString *) system;
- (Vector) coordinatesFromCoordinateSystemString:(NSString *) system_x_y_z;
- (BOOL) addShipWithRole:(NSString *) desc nearPosition:(Vector) pos withCoordinateSystem:(NSString *) system;
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc atPosition:(Vector) pos withCoordinateSystem:(NSString *) system;
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc nearPosition:(Vector) pos withCoordinateSystem:(NSString *) system;
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc nearPosition:(Vector) pos withCoordinateSystem:(NSString *) system withinRadius:(GLfloat) radius;
- (HPVector) coordinatesForPosition:(HPVector) pos withCoordinateSystem:(NSString *) system returningScalar:(GLfloat*) my_scalar;
- (NSString *) expressPosition:(HPVector) pos inCoordinateSystem:(NSString *) system;
- (HPVector) legacyPositionFrom:(HPVector) pos asCoordinateSystem:(NSString *) system;
- (HPVector) coordinatesFromCoordinateSystemString:(NSString *) system_x_y_z;
- (BOOL) addShipWithRole:(NSString *) desc nearPosition:(HPVector) pos withCoordinateSystem:(NSString *) system;
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc atPosition:(HPVector) pos withCoordinateSystem:(NSString *) system;
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc nearPosition:(HPVector) pos withCoordinateSystem:(NSString *) system;
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc nearPosition:(HPVector) pos withCoordinateSystem:(NSString *) system withinRadius:(GLfloat) radius;
- (BOOL) addShips:(int) howMany withRole:(NSString *) desc intoBoundingBox:(BoundingBox) bbox;
- (BOOL) spawnShip:(NSString *) shipdesc;
- (void) witchspaceShipWithPrimaryRole:(NSString *)role;
- (ShipEntity *) spawnShipWithRole:(NSString *) desc near:(Entity *) entity;
- (OOVisualEffectEntity *) addVisualEffectAt:(Vector)pos withKey:(NSString *)key;
- (ShipEntity *) addShipAt:(Vector)pos withRole:(NSString *)role withinRadius:(GLfloat)radius;
- (NSArray *) addShipsAt:(Vector)pos withRole:(NSString *)role quantity:(unsigned)count withinRadius:(GLfloat)radius asGroup:(BOOL)isGroup;
- (OOVisualEffectEntity *) addVisualEffectAt:(HPVector)pos withKey:(NSString *)key;
- (ShipEntity *) addShipAt:(HPVector)pos withRole:(NSString *)role withinRadius:(GLfloat)radius;
- (NSArray *) addShipsAt:(HPVector)pos withRole:(NSString *)role quantity:(unsigned)count withinRadius:(GLfloat)radius asGroup:(BOOL)isGroup;
- (NSArray *) addShipsToRoute:(NSString *)route withRole:(NSString *)role quantity:(unsigned)count routeFraction:(double)routeFraction asGroup:(BOOL)isGroup;
- (BOOL) roleIsPirateVictim:(NSString *)role;
@ -370,7 +381,7 @@ enum
- (void) addWitchspaceJumpEffectForShip:(ShipEntity *)ship;
- (GLfloat) safeWitchspaceExitDistance;
- (void) setUpBreakPattern:(Vector)pos orientation:(Quaternion)q forDocking:(BOOL)forDocking;
- (void) setUpBreakPattern:(HPVector)pos orientation:(Quaternion)q forDocking:(BOOL)forDocking;
- (BOOL) witchspaceBreakPattern;
- (void) setWitchspaceBreakPattern:(BOOL)newValue;
@ -464,9 +475,9 @@ enum
- (ShipEntity *) makeDemoShipWithRole:(NSString *)role spinning:(BOOL)spinning;
- (BOOL) isVectorClearFromEntity:(Entity *) e1 toDistance:(double)dist fromPoint:(Vector) p2;
- (Entity*) hazardOnRouteFromEntity:(Entity *) e1 toDistance:(double)dist fromPoint:(Vector) p2;
- (Vector) getSafeVectorFromEntity:(Entity *) e1 toDistance:(double)dist fromPoint:(Vector) p2;
- (BOOL) isVectorClearFromEntity:(Entity *) e1 toDistance:(double)dist fromPoint:(HPVector) p2;
- (Entity*) hazardOnRouteFromEntity:(Entity *) e1 toDistance:(double)dist fromPoint:(HPVector) p2;
- (HPVector) getSafeVectorFromEntity:(Entity *) e1 toDistance:(double)dist fromPoint:(HPVector) p2;
- (ShipEntity *) firstShipHitByLaserFromShip:(ShipEntity *)srcEntity inDirection:(OOWeaponFacing)direction offset:(Vector)offset gettingRangeFound:(GLfloat*)range_ptr;
- (Entity *) firstEntityTargetedByPlayer;
@ -634,13 +645,13 @@ enum
- (NSString*) brochureDescriptionWithDictionary:(NSDictionary*) dict standardEquipment:(NSArray*) extras optionalEquipment:(NSArray*) options;
- (Vector) getWitchspaceExitPosition;
- (Vector) randomizeFromSeedAndGetWitchspaceExitPosition;
- (Vector) getWitchspaceExitPositionResettingRandomSeed:(BOOL)resetSeed;
- (HPVector) getWitchspaceExitPosition;
- (HPVector) randomizeFromSeedAndGetWitchspaceExitPosition;
- (HPVector) getWitchspaceExitPositionResettingRandomSeed:(BOOL)resetSeed;
- (Quaternion) getWitchspaceExitRotation;
- (Vector) getSunSkimStartPositionForShip:(ShipEntity*) ship;
- (Vector) getSunSkimEndPositionForShip:(ShipEntity*) ship;
- (HPVector) getSunSkimStartPositionForShip:(ShipEntity*) ship;
- (HPVector) getSunSkimEndPositionForShip:(ShipEntity*) ship;
- (NSArray*) listBeaconsWithCode:(NSString*) code;
@ -742,6 +753,7 @@ OOINLINE Universe *OOGetUniverse(void)
#define DESC_PLURAL(key,count) (OOLookUpPluralDescriptionPRIV(key "", count))
// Not for direct use.
NSComparisonResult populatorPrioritySort(id a, id b, void *context);
NSString *OOLookUpDescriptionPRIV(NSString *key);
NSString *OOLookUpPluralDescriptionPRIV(NSString *key, NSInteger count);

File diff suppressed because it is too large Load Diff

View File

@ -122,14 +122,14 @@ RANROTSeed MakeRanrotSeed(unsigned seed)
RanrotWithSeed(&result);
RanrotWithSeed(&result);
RanrotWithSeed(&result);
return result;
}
RANROTSeed RanrotSeedFromRNGSeed(RNG_Seed seed)
{
return MakeRanrotSeed(rnd_seed.a * 0x1000000 + rnd_seed.b * 0x10000 + rnd_seed.c * 0x100 + rnd_seed.d);
return MakeRanrotSeed(seed.a * 0x1000000 + seed.b * 0x10000 + seed.c * 0x100 + seed.d);
}