TrayObject *vec(TrayLangState *state, int arg_num) { TrayObject *x = traylang_get_obj(state); check(x, "vec x arg error"); TrayObject *y = traylang_get_obj(state); check(y, "vec y arg error"); TrayObject *z = traylang_get_obj(state); check(z, "vec z arg error"); Vector3D *v = malloc(sizeof(Vector3D)); check_mem(v); *v = vector3d(x->number, y->number, z->number); return traylang_new_cdata(state, v); error: return NULL; }
void Game::SetTimeAccel(TimeAccel t) { // don't want player to spin like mad when hitting time accel if ((t != m_timeAccel) && (t > TIMEACCEL_1X) && m_player->GetPlayerController()->GetRotationDamping()) { m_player->SetAngVelocity(vector3d(0,0,0)); m_player->SetTorque(vector3d(0,0,0)); m_player->SetAngThrusterState(vector3d(0.0)); } // Give all ships a half-step acceleration to stop autopilot overshoot if (t < m_timeAccel) for (Space::BodyIterator i = m_space->BodiesBegin(); i != m_space->BodiesEnd(); ++i) if ((*i)->IsType(Object::SHIP)) (static_cast<Ship*>(*i))->TimeAccelAdjust(0.5f * GetTimeStep()); m_timeAccel = t; if (m_timeAccel == TIMEACCEL_PAUSED || m_timeAccel == TIMEACCEL_HYPERSPACE) { m_requestedTimeAccel = m_timeAccel; m_forceTimeAccel = false; } }
void FPSupBSpline::eval( double u, double v, vector3d &pos, vector3d &nor ) const { assert( 0.0 <= u && u <= 1.0 ); assert( 0.0 <= v && v <= 1.0 ); sbs::vector3 p00, pu0, pu1, pv0, pv1, tang_u, tang_v, nor1, nor2 ; const sbs::real vv = 1.0-v ; eval_sup_bspline( sup_bsp, &p00, u, vv ); pos = vector3d( p00.x, p00.y, p00.z ); // calculo de la normal a partir de las tangentes de la función, // calculadas usando derivacion numérica const sbs::real delta = 0.005 ; const sbs::real u0 = ( delta <= u ) ? u-delta : u, u1 = ( u+delta <= 1.0 ) ? u+delta : u, v0 = ( vv+delta <= 1.0 ) ? vv+delta : vv, v1 = ( delta <= vv ) ? vv-delta : vv ; eval_sup_bspline( sup_bsp, &pu0, u0, vv ); eval_sup_bspline( sup_bsp, &pu1, u1, vv ); sbs::v3_resta( &tang_u, &pu1, &pu0 ); eval_sup_bspline( sup_bsp, &pv0, u, v0); eval_sup_bspline( sup_bsp, &pv1, u, v1); sbs::v3_resta( &tang_v, &pv1, &pv0 ); sbs::v3_provec( &nor1, &tang_u, &tang_v ); sbs::v3_normaliza( &nor2, &nor1 ); nor = vector3d(nor2.x,nor2.y,nor2.z) ; }
bool CPlayer::initEntity() { m_Position = vector3d(200, 337, 0.5); m_State = PLAYSTATE::START; m_Acceleration = vector2d(0.5f, 0); this->m_isJump = true; m_Velocity = vector2d(9.8, 9.8); this->loadSprite(); this->m_Bounding = new CBox2D(0, 0, 0, 0); return true; }
/* XXX THIS and PositionDockedShip do almost the same thing */ void SpaceStation::OrientDockedShip(Ship *ship, int port) const { SpaceStationType::positionOrient_t dport; if (!m_type->GetDockAnimPositionOrient(port, m_type->numDockingStages, 1.0f, vector3d(0.0), dport, ship)) { Error("Space station model %s does not specify valid ship_dock_anim positions", m_type->modelName); } // const positionOrient_t *dport = &this->port[port]; const int dockMethod = m_type->dockMethod; if (dockMethod == SpaceStationType::SURFACE) { matrix4x4d stationRot; GetRotMatrix(stationRot); vector3d port_z = dport.xaxis.Cross(dport.yaxis); matrix4x4d rot = stationRot * matrix4x4d::MakeRotMatrix(dport.xaxis, dport.yaxis, port_z); vector3d pos = GetPosition() + stationRot*dport.pos; // position with wheels perfectly on ground :D Aabb aabb; ship->GetAabb(aabb); pos += stationRot*vector3d(0,-aabb.min.y,0); ship->SetPosition(pos); ship->SetRotMatrix(rot); } }
int main() { vector3d t = vector3d(1.0,1.0,1.0); vector3d u = vector3d(1.0,1.0,1.0); double length = t.length(); double dot = t.dotproduct(u); vector3d c = t.crossproduct(u); t.out(); u.out(); c.out(); printf("Length =%f\n", length); t.translation(1.0,1.0,1.0); vector3d *w; w = new vector3d(2.0,2.0,2.0); w->out(); delete w; vector3d pts[3]={vector3d(0.,0.,0.),vector3d(0.,0.,0.),vector3d(0.,0.,0.)}; for (int i=0; i<3; i++) { pts[i].out(); } }
std::unique_ptr<bsp_tree_node> MakeTree(std::vector<pcs_polygon> &polygons, vector3d &Max, vector3d &Min) { std::vector<int> polylist(polygons.size()); for (unsigned int i = 0; i < polylist.size(); i++) { polylist[i] = i; } MakeBound(Max, Min, polylist, polygons); // we want to give padding so as to not make the outermost bounding regions too tight Max = Max +vector3d(0.1f, 0.1f, 0.1f); Min = Min -vector3d(0.1f, 0.1f, 0.1f); if (polygons.empty()) { return std::unique_ptr<bsp_tree_node>((bsp_tree_node*)NULL); } wxLongLong time = wxGetLocalTimeMillis(); PCS_Model::BSP_CUR_DEPTH = 0; std::unique_ptr<bsp_tree_node> node = GenerateTreeRecursion(polygons, polylist); PCS_Model::BSP_TREE_TIME += (wxGetLocalTimeMillis() - time).ToLong(); return node; }
void Missile::StaticUpdate(const float timeStep) { // Note: direct call to AI->TimeStepUpdate if (m_curAICmd!=nullptr) m_curAICmd->TimeStepUpdate(); //Add smoke trails for missiles on thruster state static double s_timeAccum = 0.0; s_timeAccum += timeStep; if (!is_equal_exact(GetThrusterState().LengthSqr(), 0.0) && (s_timeAccum > 4 || 0.1*Pi::rng.Double() < timeStep)) { s_timeAccum = 0.0; const vector3d pos = GetOrient() * vector3d(0, 0 , 5); const float speed = std::min(10.0*GetVelocity().Length()*std::max(1.0,fabs(GetThrusterState().z)),100.0); SfxManager::AddThrustSmoke(this, speed, pos); } }
void rectify::powerMaxEigenVec(Matrix3f inputMat, vector3d& outputVec) { Matrix3f symmetricFund; inputMat = inputMat * 1e-20; symmetricFund = inputMat.ReturnSymmetric(); //returned AtA vector3d dummyMaxEigenVec; vector3d output = vector3d(1.0, 0.0, 0.0); //symmetricFund = symmetricFund * 1e-15; int _size = 3; bool powerRepeat = true; float diag = 0.0; int totalCounter = 0; bool thresReached = false; vector3d diff; int counter; //dummy eigenVecs for value comparision during iteration while(powerRepeat) { //save maxEigenVec to dummy dummyMaxEigenVec = output; //do matrix multiplication output = symmetricFund * dummyMaxEigenVec; //find maximum value in eigenVec and make it 1 diag = output.x; if(fabs(output.y) > fabs(diag)) diag = output.y; if(fabs(output.z) > fabs(diag)) diag = output.z; output /= diag; //comparision for repitition of iteration diff = dummyMaxEigenVec - output; if(fabs(diff.x) < 0.00005 && fabs(diff.y) < 0.00005 && fabs(diff.z) < 0.00005) thresReached = true; totalCounter++; if(thresReached == true || totalCounter > 20) powerRepeat = false; if(!powerRepeat) { output.Display("op"); output.Normalize(); outputVec = output; if(totalCounter > 200){std::cout<<std::endl<<" power not converging "<<std::endl;} } } }
void PlayerShipController::StaticUpdate(const float timeStep) { vector3d v; matrix4x4d m; if (m_ship->GetFlightState() == Ship::FLYING) { switch (m_flightControlState) { case CONTROL_FIXSPEED: PollControls(timeStep, true); if (IsAnyLinearThrusterKeyDown()) break; v = -m_ship->GetOrient().VectorZ() * m_setSpeed; if (m_setSpeedTarget) { v += m_setSpeedTarget->GetVelocityRelTo(m_ship->GetFrame()); } m_ship->AIMatchVel(v); break; case CONTROL_FIXHEADING_FORWARD: case CONTROL_FIXHEADING_BACKWARD: PollControls(timeStep, true); if (IsAnyAngularThrusterKeyDown()) break; v = m_ship->GetVelocity().NormalizedSafe(); if (m_flightControlState == CONTROL_FIXHEADING_BACKWARD) v = -v; m_ship->AIFaceDirection(v); break; case CONTROL_MANUAL: PollControls(timeStep, false); break; case CONTROL_AUTOPILOT: if (m_ship->AIIsActive()) break; Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X); // AIMatchVel(vector3d(0.0)); // just in case autopilot doesn't... // actually this breaks last timestep slightly in non-relative target cases m_ship->AIMatchAngVelObjSpace(vector3d(0.0)); if (m_ship->GetFrame()->IsRotFrame()) SetFlightControlState(CONTROL_FIXSPEED); else SetFlightControlState(CONTROL_MANUAL); m_setSpeed = 0.0; break; default: assert(0); break; } } else SetFlightControlState(CONTROL_MANUAL); //call autopilot AI, if active (also applies to set speed and heading lock modes) OS::EnableFPE(); m_ship->AITimeStep(timeStep); OS::DisableFPE(); }
static int l_vector_unit(lua_State *L) { LUA_DEBUG_START(L); if (lua_isnumber(L, 1)) { double x = luaL_checknumber(L, 1); double y = luaL_checknumber(L, 2); double z = luaL_checknumber(L, 3); const vector3d v = vector3d(x, y, z); LuaVector::PushToLua(L, v.NormalizedSafe()); } else { const vector3d *v = LuaVector::CheckFromLua(L, 1); LuaVector::PushToLua(L, v->NormalizedSafe()); } LUA_DEBUG_END(L, 1); return 1; }
DynamicBody::DynamicBody(): ModelBody() { m_flags = Body::FLAG_CAN_MOVE_FRAME; m_orient = matrix4x4d::Identity(); m_oldOrient = m_orient; m_oldAngDisplacement = vector3d(0.0); m_force = vector3d(0.0); m_torque = vector3d(0.0); m_vel = vector3d(0.0); m_angVel = vector3d(0.0); m_mass = 1; m_angInertia = 1; m_massRadius = 1; m_enabled = true; m_atmosForce = vector3d(0.0); m_gravityForce = vector3d(0.0); m_externalForce = vector3d(0.0); // do external forces calc instead? }
/* * Function: SpawnShipNear * * Create a ship and place it in space near the given <Body>. * * > ship = Space.SpawnShip(type, body, min, max, hyperspace) * * Parameters: * * type - the name of the ship * * body - the <Body> near which the ship should be spawned * * min - minimum distance from the body to place the ship, in Km * * max - maximum distance to place the ship * * hyperspace - optional table containing hyperspace entry information. If * this is provided the ship will not spawn directly. Instead, * a hyperspace cloud will be created that the ship will exit * from. The table contains two elements, a <SystemPath> for * the system the ship is travelling from, and the due * date/time that the ship should emerge from the cloud. * * Return: * * ship - a <Ship> object for the new ship * * Example: * * > -- spawn a ship 10km from the player * > local ship = Ship.SpawnNear("viper_police_craft", Game.player, 10, 10) * * Availability: * * alpha 10 * * Status: * * experimental */ static int l_space_spawn_ship_near(lua_State *l) { if (!Pi::game) luaL_error(l, "Game is not started"); LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); if (! ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); Body *nearbody = LuaObject<Body>::CheckFromLua(2); float min_dist = luaL_checknumber(l, 3); float max_dist = luaL_checknumber(l, 4); SystemPath *path = 0; double due = -1; _unpack_hyperspace_args(l, 5, path, due); Ship *ship = new Ship(type); assert(ship); Body *thing = _maybe_wrap_ship_with_cloud(ship, path, due); // XXX protect against spawning inside the body Frame * newframe = nearbody->GetFrame(); const vector3d newPosition = (MathUtil::RandomPointOnSphere(min_dist, max_dist)* 1000.0) + nearbody->GetPosition(); // If the frame is rotating and the chosen position is too far, use non-rotating parent. // Otherwise the ship will be given a massive initial velocity when it's bumped out of the // rotating frame in the next update if (newframe->IsRotFrame() && newframe->GetRadius() < newPosition.Length()) { assert(newframe->GetParent()); newframe = newframe->GetParent(); } thing->SetFrame(newframe);; thing->SetPosition(newPosition); thing->SetVelocity(vector3d(0,0,0)); Pi::game->GetSpace()->AddBody(thing); LuaObject<Ship>::PushToLua(ship); LUA_DEBUG_END(l, 1); return 1; }
Player::Player(ShipType::Type shipType): Ship(shipType) { m_mouseActive = false; m_invertMouse = false; m_flightControlState = CONTROL_MANUAL; m_killCount = 0; m_knownKillCount = 0; m_setSpeedTarget = 0; m_navTarget = 0; m_combatTarget = 0; UpdateMass(); float deadzone = Pi::config.Float("JoystickDeadzone"); m_joystickDeadzone = deadzone * deadzone; m_accumTorque = vector3d(0,0,0); }
void DynamicBody::CalcExternalForce() { // gravity Body *body = GetFrame()->GetBodyFor(); if (body && !body->IsType(Object::SPACESTATION)) { // they ought to have mass though... vector3d b1b2 = GetPosition(); double m1m2 = GetMass() * body->GetMass(); double invrsqr = 1.0 / b1b2.LengthSqr(); double force = G*m1m2 * invrsqr; m_externalForce = -b1b2 * sqrt(invrsqr) * force; } else m_externalForce = vector3d(0.0); m_gravityForce = m_externalForce; // atmospheric drag const double speed = m_vel.Length(); if ((speed > 0) && body && body->IsType(Object::PLANET)) { Planet *planet = static_cast<Planet*>(body); double dist = GetPosition().Length(); double pressure, density; planet->GetAtmosphericState(dist, &pressure, &density); const double radius = GetBoundingRadius(); const double AREA = radius; // ^^^ yes that is as stupid as it looks const double DRAG_COEFF = 0.1; // 'smooth sphere' vector3d dragDir = -m_vel.Normalized(); vector3d fDrag = 0.5*density*speed*speed*AREA*DRAG_COEFF*dragDir; // make this a bit less daft at high time accel // only allow atmosForce to increase by .1g per frame vector3d f1g = m_atmosForce + dragDir * GetMass(); if (fDrag.LengthSqr() > f1g.LengthSqr()) m_atmosForce = f1g; else m_atmosForce = fDrag; m_externalForce += m_atmosForce; } // centrifugal and coriolis forces for rotating frames vector3d angRot = GetFrame()->GetAngVelocity(); if (angRot.LengthSqr() > 0.0) { m_externalForce -= m_mass * angRot.Cross(angRot.Cross(GetPosition())); // centrifugal m_externalForce -= 2 * m_mass * angRot.Cross(GetVelocity()); // coriolis } }
vector3d Frame::GetInterpPositionRelTo(const Frame *relTo) const { // early-outs for simple cases, required for accuracy in large systems if (this == relTo) return vector3d(0,0,0); if (GetParent() == relTo) return m_interpPos; // relative to parent if (relTo->GetParent() == this) { // relative to child if (!relTo->IsRotFrame()) return -relTo->m_interpPos; else return -relTo->m_interpPos * relTo->m_interpOrient; } if (relTo->GetParent() == GetParent()) { // common parent if (!relTo->IsRotFrame()) return m_interpPos - relTo->m_interpPos; else return (m_interpPos - relTo->m_interpPos) * relTo->m_interpOrient; } vector3d diff = m_rootInterpPos - relTo->m_rootInterpPos; if (relTo->IsRotFrame()) return diff * relTo->m_rootInterpOrient; else return diff; }
void WeaponSystem::update(ent_ptr<EntityManager> em, ent_ptr<EventManager> events, double dt) { for (auto entity : em->entities_with_components<WeaponComponent>()) { ent_ptr<WeaponComponent> wc = entity.component<WeaponComponent>(); if (wc->firing) { ent_ptr<PosOrientComponent> ownerPoc = entity.component<PosOrientComponent>(); ent_ptr<DynamicsComponent> ownerDc = entity.component<DynamicsComponent>(); auto ownerFc = entity.component<FrameComponent>(); //laser bolt Entity laser = em->create(); laser.assign<GraphicComponent>(new LaserBoltGraphic(m_renderer)); laser.assign<PosOrientComponent>(ownerPoc->pos, ownerPoc->orient); laser.assign<ProjectileComponent>(ownerDc->vel, ownerPoc->orient * vector3d(0, 0, -500), 3.0, entity); laser.assign<FrameComponent>(ownerFc->frame); wc->firing = false; } } }
void Ship::TimeStepUpdate(const float timeStep) { // If docked, station is responsible for updating position/orient of ship // but we call this crap anyway and hope it doesn't do anything bad vector3d maxThrust = GetMaxThrust(m_thrusters); vector3d thrust = vector3d(maxThrust.x*m_thrusters.x, maxThrust.y*m_thrusters.y, maxThrust.z*m_thrusters.z); AddRelForce(thrust); AddRelTorque(GetShipType().angThrust * m_angThrusters); DynamicBody::TimeStepUpdate(timeStep); // fuel use decreases mass, so do this as the last thing in the frame UpdateFuel(timeStep, thrust); if (m_landingGearAnimation) static_cast<SceneGraph::Model*>(GetModel())->UpdateAnimations(); }
vector3d SpaceStation::GetTargetIndicatorPosition(const Frame *relTo) const { // return the next waypoint if permission has been granted for player, // and the docking point's position once the docking anim starts for (int i=0; i<MAX_DOCKING_PORTS; i++) { if (i >= m_type->numDockingPorts) break; if ((m_shipDocking[i].ship == Pi::player) && (m_shipDocking[i].stage > 0)) { SpaceStationType::positionOrient_t dport; if (!m_type->GetShipApproachWaypoints(i, m_shipDocking[i].stage+1, dport)) PiVerify(m_type->GetDockAnimPositionOrient(i, m_type->numDockingStages, 1.0f, vector3d(0.0), dport, m_shipDocking[i].ship)); vector3d v = GetInterpPositionRelTo(relTo); return v + GetInterpOrientRelTo(relTo) * dport.pos; } } return GetInterpPositionRelTo(relTo); }
void Ship::TestLanded() { m_testLanded = false; if (m_launchLockTimeout > 0.0f) return; if (m_wheelState < 1.0f) return; if (GetFrame()->GetBodyFor()->IsType(Object::PLANET)) { double speed = GetVelocity().Length(); vector3d up = GetPosition().Normalized(); const double planetRadius = static_cast<Planet*>(GetFrame()->GetBodyFor())->GetTerrainHeight(up); if (speed < MAX_LANDING_SPEED) { // orient the damn thing right // Q: i'm totally lost. why is the inverse of the body rot matrix being used? // A: NFI. it just works this way matrix4x4d rot; GetRotMatrix(rot); matrix4x4d invRot = rot.InverseOf(); // check player is sortof sensibly oriented for landing const double dot = vector3d(invRot[1], invRot[5], invRot[9]).Normalized().Dot(up); if (dot > 0.99) { Aabb aabb; GetAabb(aabb); // position at zero altitude SetPosition(up * (planetRadius - aabb.min.y)); vector3d forward = rot * vector3d(0,0,1); vector3d other = up.Cross(forward).Normalized(); forward = other.Cross(up); rot = matrix4x4d::MakeRotMatrix(other, up, forward); rot = rot.InverseOf(); SetRotMatrix(rot); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetForce(vector3d(0, 0, 0)); SetTorque(vector3d(0, 0, 0)); // we don't use DynamicBody::Disable because that also disables the geom, and that must still get collisions DisableBodyOnly(); ClearThrusterState(); m_flightState = LANDED; Sound::PlaySfx("Rough_Landing", 1.0f, 1.0f, 0); Pi::luaOnShipLanded->Queue(this, GetFrame()->GetBodyFor()); } } } }
static void MiningLaserSpawnTastyStuff(Frame *f, const SBody *asteroid, const vector3d &pos) { Equip::Type t; if (20*Pi::rng.Fixed() < asteroid->m_metallicity) { t = Equip::PRECIOUS_METALS; } else if (8*Pi::rng.Fixed() < asteroid->m_metallicity) { t = Equip::METAL_ALLOYS; } else if (Pi::rng.Fixed() < asteroid->m_metallicity) { t = Equip::METAL_ORE; } else if (Pi::rng.Fixed() < fixed(1,2)) { t = Equip::WATER; } else { t = Equip::RUBBISH; } CargoBody *cargo = new CargoBody(t); cargo->SetFrame(f); cargo->SetPosition(pos); cargo->SetVelocity(Pi::rng.Double(100.0,200.0)*vector3d(Pi::rng.Double()-.5, Pi::rng.Double()-.5, Pi::rng.Double()-.5)); Pi::game->GetSpace()->AddBody(cargo); }
// Fly to "vicinity" of body AICmdFlyTo::AICmdFlyTo(Ship *ship, Body *target) : AICommand (ship, CMD_FLYTO) { double dist = std::max(VICINITY_MIN, VICINITY_MUL*MaxEffectRad(target, ship)); if (target->IsType(Object::SPACESTATION) && static_cast<SpaceStation *>(target)->IsGroundStation()) { matrix4x4d rot; target->GetRotMatrix(rot); m_posoff = target->GetPosition() + dist * vector3d(rot[4], rot[5], rot[6]); // up vector for starport m_targframe = target->GetFrame(); } else { m_targframe = GetNonRotFrame(target); m_posoff = dist * m_ship->GetPositionRelTo(m_targframe).Normalized(); m_posoff += target->GetPosition(); } m_endvel = 0; m_tangent = 0; m_state = -1; m_frame = 0; // check if we're already close enough if (dist > m_ship->GetPositionRelTo(target).Length()) m_state = 5; }
void v3math_object::test<6>() { F32 x = 2.32f, y = 1.212f, z = -.12f; LLVector3 vec3(x,y,z),vec3a; vec3.abs(); ensure("1:abs:Fail ", ((x == vec3.mV[VX]) && (y == vec3.mV[VY]) && (-z == vec3.mV[VZ]))); vec3a.setVec(vec3); ensure("2:setVec:Fail to initialize ", (vec3a == vec3)); const F32 vec[3] = {1.2f ,3.2f, -4.2f}; vec3.clearVec(); vec3.setVec(vec); ensure("3:setVec:Fail to initialize ", ((1.2f == vec3.mV[VX]) && (3.2f == vec3.mV[VY]) && (-4.2f == vec3.mV[VZ]))); vec3a.clearVec(); LLVector3d vector3d(vec3); vec3a.setVec(vector3d); ensure("4:setVec:Fail to initialize ", (vec3 == vec3a)); LLVector4 vector4(vec3); vec3a.clearVec(); vec3a.setVec(vector4); ensure("5:setVec:Fail to initialize ", (vec3 == vec3a)); }
Frame *Frame::Unserialize(Serializer::Reader &rd, Space *space, Frame *parent) { Frame *f = new Frame(); f->m_parent = parent; f->m_flags = rd.Int32(); f->m_radius = rd.Double(); f->m_label = rd.String(); f->m_pos = rd.Vector3d(); for (int i=0; i<9; i++) f->m_orient[i] = rd.Double(); f->m_angSpeed = rd.Double(); f->m_sbody = space->GetSystemBodyByIndex(rd.Int32()); f->m_astroBodyIndex = rd.Int32(); f->m_vel = vector3d(0.0); for (int i=rd.Int32(); i>0; --i) { f->m_children.push_back(Unserialize(rd, space, f)); } Sfx::Unserialize(rd, f); f->ClearMovement(); return f; }
/* * Function: SpawnShip * * Create a ship and place it somewhere in space. * * > ship = Space.SpawnShip(type, min, max, hyperspace) * * Parameters: * * type - the name of the ship * * min - minimum distance from the system centre (usually the primary star) * to place the ship, in AU * * max - maximum distance to place the ship * * hyperspace - optional table containing hyperspace entry information. If * this is provided the ship will not spawn directly. Instead, * a hyperspace cloud will be created that the ship will exit * from. The table contains two elements, a <SystemPath> for * the system the ship is travelling from, and the due * date/time that the ship should emerge from the cloud. * In this case min and max arguments are ignored. * * Return: * * ship - a <Ship> object for the new ship * * Examples: * * > -- spawn a ship 5-6AU from the system centre * > local ship = Ship.Spawn("eagle_lrf", 5, 6) * * > -- spawn a ship in the ~11AU hyperspace area and make it appear that it * > -- came from Sol and will arrive in ten minutes * > local ship = Ship.Spawn( * > "flowerfairy", 9, 11, * > { SystemPath:New(0,0,0), Game.time + 600 } * > ) * * Availability: * * alpha 10 * * Status: * * experimental */ static int l_space_spawn_ship(lua_State *l) { if (!Pi::game) luaL_error(l, "Game is not started"); LUA_DEBUG_START(l); const char *type = luaL_checkstring(l, 1); if (! ShipType::Get(type)) luaL_error(l, "Unknown ship type '%s'", type); float min_dist = luaL_checknumber(l, 2); float max_dist = luaL_checknumber(l, 3); SystemPath *path = NULL; double due = -1; _unpack_hyperspace_args(l, 4, path, due); Ship *ship = new Ship(type); assert(ship); Body *thing = _maybe_wrap_ship_with_cloud(ship, path, due); // XXX protect against spawning inside the body thing->SetFrame(Pi::game->GetSpace()->GetRootFrame()); if (path == NULL) thing->SetPosition(MathUtil::RandomPointOnSphere(min_dist, max_dist)*AU); else // XXX broken. this is ignoring min_dist & max_dist. otoh, what's the // correct behaviour given there's now a fixed hyperspace exit point? thing->SetPosition(Pi::game->GetSpace()->GetHyperspaceExitPoint(*path)); thing->SetVelocity(vector3d(0,0,0)); Pi::game->GetSpace()->AddBody(thing); LuaShip::PushToLua(ship); LUA_DEBUG_END(l, 1); return 1; }
Frame *Frame::FromJson(const Json::Value &jsonObj, Space *space, Frame *parent, double at_time) { Frame *f = new Frame(); f->m_parent = parent; if (!jsonObj.isMember("frame")) throw SavedGameCorruptException(); Json::Value frameObj = jsonObj["frame"]; if (!frameObj.isMember("flags")) throw SavedGameCorruptException(); if (!frameObj.isMember("radius")) throw SavedGameCorruptException(); if (!frameObj.isMember("label")) throw SavedGameCorruptException(); if (!frameObj.isMember("pos")) throw SavedGameCorruptException(); if (!frameObj.isMember("ang_speed")) throw SavedGameCorruptException(); if (!frameObj.isMember("init_orient")) throw SavedGameCorruptException(); if (!frameObj.isMember("index_for_system_body")) throw SavedGameCorruptException(); if (!frameObj.isMember("index_for_astro_body")) throw SavedGameCorruptException(); f->m_flags = frameObj["flags"].asInt(); f->m_radius = StrToDouble(frameObj["radius"].asString()); f->m_label = frameObj["label"].asString(); JsonToVector(&(f->m_pos), frameObj, "pos"); f->m_angSpeed = StrToDouble(frameObj["ang_speed"].asString()); matrix3x3d orient; JsonToMatrix(&orient, frameObj, "init_orient"); f->SetInitialOrient(orient, at_time); f->m_sbody = space->GetSystemBodyByIndex(frameObj["index_for_system_body"].asUInt()); f->m_astroBodyIndex = frameObj["index_for_astro_body"].asUInt(); f->m_vel = vector3d(0.0); // m_vel is set to zero. if (!frameObj.isMember("child_frames")) throw SavedGameCorruptException(); Json::Value childFrameArray = frameObj["child_frames"]; if (!childFrameArray.isArray()) throw SavedGameCorruptException(); for (unsigned int i = 0; i < childFrameArray.size(); ++i) { f->m_children.push_back(FromJson(childFrameArray[i], space, f, at_time)); } SfxManager::FromJson(frameObj, f); f->ClearMovement(); return f; }
void ObjectViewerView::Draw3D() { static float rot; rot += 0.1; glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float znear, zfar; Pi::worldView->GetNearFarClipPlane(&znear, &zfar); float fracH = znear / Pi::GetScrAspect(); glFrustum(-znear, znear, -fracH, fracH, znear, zfar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnable(GL_LIGHT0); Render::State::SetZnearZfar(znear, zfar); if (Pi::MouseButtonState(SDL_BUTTON_RIGHT)) { int m[2]; Pi::GetMouseMotion(m); m_camRot = matrix4x4d::RotateXMatrix(-0.002*m[1]) * matrix4x4d::RotateYMatrix(-0.002*m[0]) * m_camRot; } Body *body = Pi::player->GetNavTarget(); if (body) { float lightPos[4]; if (body->IsType(Object::STAR)) lightPos[0] = lightPos[1] = lightPos[2] = lightPos[3] = 0; else { lightPos[0] = lightPos[1] = lightPos[2] = 0.577f; lightPos[3] = 0; } glLightfv(GL_LIGHT0, GL_POSITION, lightPos); body->Render(vector3d(0,0,-viewingDist), m_camRot); } }
vector3d SpaceStation::GetTargetIndicatorPosition(const Frame *relTo) const { // return the next waypoint if permission has been granted for player, // and the docking point's position once the docking anim starts for (int i=0; i<MAX_DOCKING_PORTS; i++) { if (i >= m_type->numDockingPorts) break; if ((m_shipDocking[i].ship == Pi::player) && (m_shipDocking[i].stage > 0)) { SpaceStationType::positionOrient_t dport; if (!m_type->GetShipApproachWaypoints(i, m_shipDocking[i].stage+1, dport)) PiVerify(m_type->GetDockAnimPositionOrient(i, m_type->numDockingStages, 1.0f, vector3d(0.0), dport, m_shipDocking[i].ship)); matrix4x4d rot; GetRotMatrix(rot); matrix4x4d m; Frame::GetFrameRenderTransform(GetFrame(), relTo, m); return m * (GetInterpolatedPosition() + (rot*dport.pos)); } } return GetInterpolatedPositionRelTo(relTo); }
void GeoSphere::BuildFirstPatches() { assert(!m_patches[0].Valid()); if(m_patches[0].Valid()) return; // generate root face patches of the cube/sphere static const vector3d p1 = (vector3d( 1, 1, 1)).Normalized(); static const vector3d p2 = (vector3d(-1, 1, 1)).Normalized(); static const vector3d p3 = (vector3d(-1,-1, 1)).Normalized(); static const vector3d p4 = (vector3d( 1,-1, 1)).Normalized(); static const vector3d p5 = (vector3d( 1, 1,-1)).Normalized(); static const vector3d p6 = (vector3d(-1, 1,-1)).Normalized(); static const vector3d p7 = (vector3d(-1,-1,-1)).Normalized(); static const vector3d p8 = (vector3d( 1,-1,-1)).Normalized(); const uint64_t maxShiftDepth = GeoPatchID::MAX_SHIFT_DEPTH; m_patches[0].Reset(new GeoPatch(s_patchContext, this, p1, p2, p3, p4, 0, (0ULL << maxShiftDepth))); m_patches[1].Reset(new GeoPatch(s_patchContext, this, p4, p3, p7, p8, 0, (1ULL << maxShiftDepth))); m_patches[2].Reset(new GeoPatch(s_patchContext, this, p1, p4, p8, p5, 0, (2ULL << maxShiftDepth))); m_patches[3].Reset(new GeoPatch(s_patchContext, this, p2, p1, p5, p6, 0, (3ULL << maxShiftDepth))); m_patches[4].Reset(new GeoPatch(s_patchContext, this, p3, p2, p6, p7, 0, (4ULL << maxShiftDepth))); m_patches[5].Reset(new GeoPatch(s_patchContext, this, p8, p7, p6, p5, 0, (5ULL << maxShiftDepth))); for (int i=0; i<NUM_PATCHES; i++) { for (int j=0; j<4; j++) { m_patches[i]->edgeFriend[j] = m_patches[geo_sphere_edge_friends[i][j]].Get(); } } for (int i=0; i<NUM_PATCHES; i++) { m_patches[i]->RequestSinglePatch(); } m_initStage = eRequestedFirstPatches; }
static void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, const vector3d &pos) { Equip::Type t; if (20*Pi::rng.Fixed() < asteroid->GetMetallicity()) { t = Equip::PRECIOUS_METALS; } else if (8*Pi::rng.Fixed() < asteroid->GetMetallicity()) { t = Equip::METAL_ALLOYS; } else if (Pi::rng.Fixed() < asteroid->GetMetallicity()) { t = Equip::METAL_ORE; } else if (Pi::rng.Fixed() < fixed(1,2)) { t = Equip::WATER; } else { t = Equip::RUBBISH; } CargoBody *cargo = new CargoBody(t); cargo->SetFrame(f); cargo->SetPosition(pos); const double x = Pi::rng.Double(); vector3d dir = pos.Normalized(); dir.ArbRotate(vector3d(x, 1-x, 0), Pi::rng.Double()-.5); cargo->SetVelocity(Pi::rng.Double(100.0,200.0) * dir); Pi::game->GetSpace()->AddBody(cargo); }