Convert space indentations to tabs
This commit is contained in:
parent
29c42d950b
commit
18f3e81fd1
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "ALFuncs.h"
|
||||
@ -168,33 +168,33 @@ namespace al{
|
||||
static void *GPA(const char *str)
|
||||
{
|
||||
if(!alLibrary){
|
||||
auto paths = spades::Split(s_alDriver, ";");
|
||||
std::string errors;
|
||||
for (const std::string &path: paths) {
|
||||
auto trimmedPath = spades::TrimSpaces(path);
|
||||
try {
|
||||
alLibrary = new spades::DynamicLibrary(trimmedPath.c_str());
|
||||
if (alLibrary) {
|
||||
SPLog("'%s' loaded", trimmedPath.c_str());
|
||||
break;
|
||||
}
|
||||
} catch (const std::exception &ex) {
|
||||
errors += trimmedPath;
|
||||
errors += ":\n";
|
||||
errors += ex.what();
|
||||
}
|
||||
}
|
||||
if (!alLibrary) {
|
||||
SPRaise("Failed to load a OpenAL driver.\n%s", errors.c_str());
|
||||
}
|
||||
auto paths = spades::Split(s_alDriver, ";");
|
||||
std::string errors;
|
||||
for (const std::string &path: paths) {
|
||||
auto trimmedPath = spades::TrimSpaces(path);
|
||||
try {
|
||||
alLibrary = new spades::DynamicLibrary(trimmedPath.c_str());
|
||||
if (alLibrary) {
|
||||
SPLog("'%s' loaded", trimmedPath.c_str());
|
||||
break;
|
||||
}
|
||||
} catch (const std::exception &ex) {
|
||||
errors += trimmedPath;
|
||||
errors += ":\n";
|
||||
errors += ex.what();
|
||||
}
|
||||
}
|
||||
if (!alLibrary) {
|
||||
SPRaise("Failed to load a OpenAL driver.\n%s", errors.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(qalGetProcAddress){
|
||||
void *v = qalGetProcAddress(str);
|
||||
if(v)
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
return alLibrary->GetSymbol(str);
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ namespace al{
|
||||
void InitEAX(void){
|
||||
ALCdevice *pDevice = NULL;
|
||||
ALCcontext *pContext = NULL;
|
||||
|
||||
|
||||
pContext = qalcGetCurrentContext();
|
||||
pDevice = qalcGetContextsDevice(pContext);
|
||||
|
||||
@ -246,9 +246,9 @@ namespace al{
|
||||
SPRaise("Extension not found: '%s'",
|
||||
ALC_EXT_EFX_NAME);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Link(void) {
|
||||
SPLog("Linking with OpenAL library.");
|
||||
L(alEnable);
|
||||
@ -306,7 +306,7 @@ namespace al{
|
||||
L(alDopplerFactor);
|
||||
L(alDopplerVelocity);
|
||||
L(alDistanceModel);
|
||||
|
||||
|
||||
L(alcCreateContext);
|
||||
L(alcMakeContextCurrent);
|
||||
L(alcProcessContext);
|
||||
@ -322,9 +322,9 @@ namespace al{
|
||||
L(alcGetEnumValue);
|
||||
L(alcGetString);
|
||||
L(alcGetIntegerv);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
const char *DescribeError(ALenum e){
|
||||
switch(e){
|
||||
case AL_NO_ERROR:
|
||||
@ -343,7 +343,7 @@ namespace al{
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CheckError(void){
|
||||
ALenum e;
|
||||
e = qalGetError();
|
||||
@ -354,7 +354,7 @@ namespace al{
|
||||
SPLog("OpenAL error %d: %s", (int)e, DescribeError(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CheckError(const char *source, const char *fun, int line){
|
||||
ALenum e;
|
||||
e = qalGetError();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,22 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
based on code of pysnip (c) Mathias Kaerlev 2011-2012.
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "Client.h"
|
||||
@ -90,18 +90,18 @@ DEFINE_SPADES_SETTING(cg_keyAutoFocus, "MiddleMouseButton");
|
||||
|
||||
namespace spades {
|
||||
namespace client {
|
||||
|
||||
|
||||
bool Client::WantsToBeClosed() {
|
||||
return readyToClose;
|
||||
}
|
||||
|
||||
|
||||
bool FirstPersonSpectate = false;
|
||||
|
||||
|
||||
void Client::Closing() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Client::NeedsAbsoluteMouseCoordinate() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(scriptedUI->NeedsInput()) {
|
||||
@ -116,20 +116,20 @@ namespace spades {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Client::MouseEvent(float x, float y) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
if(scriptedUI->NeedsInput()) {
|
||||
scriptedUI->MouseEvent(x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(IsLimboViewActive()){
|
||||
limbo->MouseEvent(x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(IsFollowing()){
|
||||
SPAssert(world != nullptr);
|
||||
/*
|
||||
@ -140,11 +140,11 @@ namespace spades {
|
||||
x = -x; y = -y;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
x = -x;
|
||||
if (!cg_invertMouseY)
|
||||
y = -y;
|
||||
|
||||
|
||||
followYaw -= x * 0.003f;
|
||||
followPitch -= y * 0.003f;
|
||||
if(followPitch < -M_PI*.45f) followPitch = -static_cast<float>(M_PI)*.45f;
|
||||
@ -156,7 +156,7 @@ namespace spades {
|
||||
if(p->IsAlive()){
|
||||
x /= GetAimDownZoomScale();
|
||||
y /= GetAimDownZoomScale();
|
||||
|
||||
|
||||
float rad = x * x + y * y;
|
||||
if(rad > 0.f) {
|
||||
if((float)cg_mouseExpPower < 0.001f ||
|
||||
@ -168,40 +168,40 @@ namespace spades {
|
||||
factor *= factor;
|
||||
rad /= factor;
|
||||
rad = powf(rad, (float)cg_mouseExpPower * 0.5f - 0.5f);
|
||||
|
||||
|
||||
// shouldn't happen...
|
||||
if(isnan(rad)) rad = 1.f;
|
||||
|
||||
|
||||
x *= rad;
|
||||
y *= rad;
|
||||
}
|
||||
|
||||
|
||||
if(aimDownState > 0.f) {
|
||||
float scale = cg_zoomedMouseSensScale;
|
||||
scale = powf(scale, aimDownState);
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
}
|
||||
|
||||
|
||||
x *= (float)cg_mouseSensitivity;
|
||||
y *= (float)cg_mouseSensitivity;
|
||||
|
||||
|
||||
if(cg_invertMouseY)
|
||||
y = -y;
|
||||
|
||||
|
||||
p->Turn(x * 0.003f, y * 0.003f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::WheelEvent(float x, float y) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
if(scriptedUI->NeedsInput()) {
|
||||
scriptedUI->WheelEvent(x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(y > .5f) {
|
||||
KeyEvent("WheelDown", true);
|
||||
KeyEvent("WheelDown", false);
|
||||
@ -210,37 +210,37 @@ namespace spades {
|
||||
KeyEvent("WheelUp", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::TextInputEvent(const std::string &ch){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
if (scriptedUI->NeedsInput() && !scriptedUI->isIgnored(ch)) {
|
||||
scriptedUI->TextInputEvent(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// we don't get "/" here anymore
|
||||
}
|
||||
|
||||
|
||||
void Client::TextEditingEvent(const std::string &ch,
|
||||
int start, int len) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
if (scriptedUI->NeedsInput() && !scriptedUI->isIgnored(ch)) {
|
||||
scriptedUI->TextEditingEvent(ch, start, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Client::AcceptsTextInput() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
if(scriptedUI->NeedsInput()) {
|
||||
return scriptedUI->AcceptsTextInput();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
AABB2 Client::GetTextInputRect() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(scriptedUI->NeedsInput()) {
|
||||
@ -248,7 +248,7 @@ namespace spades {
|
||||
}
|
||||
return AABB2();
|
||||
}
|
||||
|
||||
|
||||
static bool CheckKey(const std::string& cfg,
|
||||
const std::string& input) {
|
||||
if(cfg.empty())
|
||||
@ -272,10 +272,10 @@ namespace spades {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Client::KeyEvent(const std::string& name, bool down){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
if(scriptedUI->NeedsInput()) {
|
||||
if(!scriptedUI->isIgnored(name)) {
|
||||
scriptedUI->KeyEvent(name, down);
|
||||
@ -286,7 +286,7 @@ namespace spades {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(name == "Escape"){
|
||||
if(down){
|
||||
if(inGameLimbo){
|
||||
@ -332,13 +332,13 @@ namespace spades {
|
||||
}
|
||||
if(world->GetLocalPlayer()){
|
||||
Player *p = world->GetLocalPlayer();
|
||||
|
||||
|
||||
if(p->IsAlive() && p->GetTool() == Player::ToolBlock && down) {
|
||||
if(paletteView->KeyInput(name)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(cg_debugCorpse){
|
||||
if(name == "p" && down){
|
||||
Corpse *corp;
|
||||
@ -346,7 +346,7 @@ namespace spades {
|
||||
corp = new Corpse(renderer, map, victim);
|
||||
corp->AddImpulse(victim->GetFront() * 32.f);
|
||||
corpses.emplace_back(corp);
|
||||
|
||||
|
||||
if(corpses.size() > corpseHardLimit){
|
||||
corpses.pop_front();
|
||||
}else if(corpses.size() > corpseSoftLimit){
|
||||
@ -412,14 +412,14 @@ namespace spades {
|
||||
(!w->IsReloading()) &&
|
||||
world->GetLocalPlayer()->GetTool() == Player::ToolWeapon){
|
||||
if(world->GetLocalPlayer()->IsToolWeapon()){
|
||||
if(weapInput.secondary) {
|
||||
// if we send WeaponInput after sending Reload,
|
||||
// server might cancel the reload.
|
||||
// https://github.com/infogulch/pyspades/blob/895879ed14ddee47bb278a77be86d62c7580f8b7/pyspades/server.py#343
|
||||
hasDelayedReload = true;
|
||||
weapInput.secondary = false;
|
||||
return;
|
||||
}
|
||||
if(weapInput.secondary) {
|
||||
// if we send WeaponInput after sending Reload,
|
||||
// server might cancel the reload.
|
||||
// https://github.com/infogulch/pyspades/blob/895879ed14ddee47bb278a77be86d62c7580f8b7/pyspades/server.py#343
|
||||
hasDelayedReload = true;
|
||||
weapInput.secondary = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
world->GetLocalPlayer()->Reload();
|
||||
net->SendReload();
|
||||
@ -590,8 +590,8 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
based on code of pysnip (c) Mathias Kaerlev 2011-2012.
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "Client.h"
|
||||
@ -60,28 +60,28 @@ DEFINE_SPADES_SETTING(cg_autoFocusSpeed, "0.4");
|
||||
|
||||
namespace spades {
|
||||
namespace client {
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark - Local Entities / Effects
|
||||
|
||||
|
||||
|
||||
|
||||
void Client::RemoveAllCorpses(){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
corpses.clear();
|
||||
lastMyCorpse = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Client::RemoveAllLocalEntities(){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
localEntities.clear();
|
||||
}
|
||||
|
||||
|
||||
void Client::RemoveInvisibleCorpses(){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
decltype(corpses)::iterator it;
|
||||
std::vector<decltype(it)> its;
|
||||
int cnt = (int)corpses.size() - corpseSoftLimit;
|
||||
@ -96,13 +96,13 @@ namespace spades {
|
||||
}
|
||||
cnt--;
|
||||
}
|
||||
|
||||
|
||||
for(size_t i = 0; i < its.size(); i++)
|
||||
corpses.erase(its[i]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Player *Client::HotTrackedPlayer( hitTag_t* hitFlag ){
|
||||
if(!world)
|
||||
return nullptr;
|
||||
@ -114,10 +114,10 @@ namespace spades {
|
||||
Vector3 origin = p->GetEye();
|
||||
Vector3 dir = p->GetFront();
|
||||
World::WeaponRayCastResult result = world->WeaponRayCast(origin, dir, p);
|
||||
|
||||
|
||||
if(result.hit == false || result.player == nullptr)
|
||||
return nullptr;
|
||||
|
||||
|
||||
// don't hot track enemies (non-spectator only)
|
||||
if(result.player->GetTeamId() != p->GetTeamId() &&
|
||||
p->GetTeamId() < 2)
|
||||
@ -127,27 +127,27 @@ namespace spades {
|
||||
}
|
||||
return result.player;
|
||||
}
|
||||
|
||||
|
||||
bool Client::IsMuted() {
|
||||
// prevent to play loud sound at connection
|
||||
// caused by saved packets
|
||||
return time < worldSetTime + .05f;
|
||||
}
|
||||
|
||||
|
||||
void Client::Bleed(spades::Vector3 v){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
if(!cg_blood)
|
||||
return;
|
||||
|
||||
|
||||
// distance cull
|
||||
if((v - lastSceneDef.viewOrigin).GetPoweredLength() >
|
||||
150.f * 150.f)
|
||||
return;
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
|
||||
Vector4 color = {0.5f, 0.02f, 0.04f, 1.f};
|
||||
for(int i = 0; i < 10; i++){
|
||||
@ -162,11 +162,11 @@ namespace spades {
|
||||
ent->SetRadius(0.1f + GetRandom()*GetRandom()*0.2f);
|
||||
ent->SetLifeTime(3.f, 0.f, 1.f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
if((int) cg_particles < 2)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if((int) cg_particles < 2)
|
||||
return;
|
||||
|
||||
color = MakeVector4(.7f, .35f, .37f, .6f);
|
||||
for(int i = 0; i < 2; i++){
|
||||
ParticleSpriteEntity *ent =
|
||||
@ -184,7 +184,7 @@ namespace spades {
|
||||
ent->SetLifeTime(.20f + GetRandom() * .2f, 0.06f, .20f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
color.w *= .1f;
|
||||
for(int i = 0; i < 1; i++){
|
||||
ParticleSpriteEntity *ent =
|
||||
@ -203,20 +203,20 @@ namespace spades {
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::EmitBlockFragments(Vector3 origin,
|
||||
IntVector3 c){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
// distance cull
|
||||
float distPowered = (origin - lastSceneDef.viewOrigin).GetPoweredLength();
|
||||
if(distPowered >
|
||||
150.f * 150.f)
|
||||
return;
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
|
||||
Vector4 color = {c.x / 255.f,
|
||||
c.y / 255.f, c.z / 255.f, 1.f};
|
||||
@ -235,10 +235,10 @@ namespace spades {
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
if ((int)cg_particles < 2)
|
||||
return;
|
||||
|
||||
|
||||
if ((int)cg_particles < 2)
|
||||
return;
|
||||
|
||||
if(distPowered <
|
||||
32.f * 32.f){
|
||||
for(int i = 0; i < 16; i++){
|
||||
@ -257,7 +257,7 @@ namespace spades {
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
color += (MakeVector4(1, 1, 1, 1) - color) * .2f;
|
||||
color.w *= .2f;
|
||||
for(int i = 0; i < 2; i++){
|
||||
@ -275,23 +275,23 @@ namespace spades {
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Client::EmitBlockDestroyFragments(IntVector3 blk,
|
||||
IntVector3 c){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
Vector3 origin = {blk.x + .5f, blk.y + .5f, blk.z + .5f};
|
||||
|
||||
|
||||
// distance cull
|
||||
if((origin - lastSceneDef.viewOrigin).GetPoweredLength() >
|
||||
150.f * 150.f)
|
||||
return;
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
|
||||
Vector4 color = {c.x / 255.f,
|
||||
c.y / 255.f, c.z / 255.f, 1.f};
|
||||
@ -310,7 +310,7 @@ namespace spades {
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::MuzzleFire(spades::Vector3 origin,
|
||||
spades::Vector3 dir,
|
||||
bool local) {
|
||||
@ -320,14 +320,14 @@ namespace spades {
|
||||
l.type = DynamicLightTypePoint;
|
||||
l.color = MakeVector3(3.f, 1.6f, 0.5f);
|
||||
flashDlights.push_back(l);
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
Vector4 color;
|
||||
Vector3 velBias = {0, 0, -0.5f};
|
||||
color = MakeVector4( .8f, .8f, .8f, .3f);
|
||||
|
||||
|
||||
// rapid smoke
|
||||
for(int i = 0; i < 2; i++){
|
||||
ParticleSpriteEntity *ent =
|
||||
@ -346,7 +346,7 @@ namespace spades {
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::GrenadeExplosion(spades::Vector3 origin){
|
||||
float dist = (origin - lastSceneDef.viewOrigin).GetLength();
|
||||
if(dist > 170.f)
|
||||
@ -354,7 +354,7 @@ namespace spades {
|
||||
grenadeVibration += 2.f / (dist + 5.f);
|
||||
if(grenadeVibration > 1.f)
|
||||
grenadeVibration = 1.f;
|
||||
|
||||
|
||||
DynamicLightParam l;
|
||||
l.origin = origin;
|
||||
l.radius = 16.f;
|
||||
@ -362,10 +362,10 @@ namespace spades {
|
||||
l.color = MakeVector3(3.f, 1.6f, 0.5f);
|
||||
l.useLensFlare = true;
|
||||
flashDlights.push_back(l);
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
if ((int)cg_particles < 1)
|
||||
return;
|
||||
|
||||
Vector3 velBias = {0,0,0};
|
||||
if(!map->ClipBox(origin.x, origin.y, origin.z)){
|
||||
if(map->ClipBox(origin.x + 1.f, origin.y, origin.z)){
|
||||
@ -387,7 +387,7 @@ namespace spades {
|
||||
velBias.z += 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vector4 color;
|
||||
color = MakeVector4( .6f, .6f, .6f, 1.f);
|
||||
// rapid smoke
|
||||
@ -407,7 +407,7 @@ namespace spades {
|
||||
ent->SetLifeTime(1.8f + GetRandom()*0.1f, 0.f, .20f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
// slow smoke
|
||||
color.w = .25f;
|
||||
for(int i = 0; i < 8; i++){
|
||||
@ -422,21 +422,21 @@ namespace spades {
|
||||
ent->SetRadius(1.5f + GetRandom()*GetRandom()*0.8f,
|
||||
0.2f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
switch ((int) cg_particles) {
|
||||
case 1:
|
||||
ent->SetLifeTime(0.8f + GetRandom() * 1.f, 0.1f, 8.f);
|
||||
break;
|
||||
case 2:
|
||||
ent->SetLifeTime(1.5f + GetRandom() * 2.f, 0.1f, 8.f);
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
ent->SetLifeTime(2.f + GetRandom() * 5.f, 0.1f, 8.f);
|
||||
break;
|
||||
}
|
||||
switch ((int) cg_particles) {
|
||||
case 1:
|
||||
ent->SetLifeTime(0.8f + GetRandom() * 1.f, 0.1f, 8.f);
|
||||
break;
|
||||
case 2:
|
||||
ent->SetLifeTime(1.5f + GetRandom() * 2.f, 0.1f, 8.f);
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
ent->SetLifeTime(2.f + GetRandom() * 5.f, 0.1f, 8.f);
|
||||
break;
|
||||
}
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
// fragments
|
||||
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
|
||||
color = MakeVector4(0.01, 0.03, 0, 1.f);
|
||||
@ -457,7 +457,7 @@ namespace spades {
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
// fire smoke
|
||||
color= MakeVector4(1.f, .7f, .4f, .2f) * 5.f;
|
||||
for(int i = 0; i < 4; i++){
|
||||
@ -478,7 +478,7 @@ namespace spades {
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::GrenadeExplosionUnderwater(spades::Vector3 origin){
|
||||
float dist = (origin - lastSceneDef.viewOrigin).GetLength();
|
||||
if(dist > 170.f)
|
||||
@ -486,18 +486,18 @@ namespace spades {
|
||||
grenadeVibration += 1.5f / (dist + 5.f);
|
||||
if(grenadeVibration > 1.f)
|
||||
grenadeVibration = 1.f;
|
||||
|
||||
if((int) cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
if((int) cg_particles < 1)
|
||||
return;
|
||||
|
||||
Vector3 velBias = {0,0,0};
|
||||
|
||||
|
||||
Vector4 color;
|
||||
color = MakeVector4( .95f, .95f, .95f, .6f);
|
||||
// water1
|
||||
Handle<IImage> img = renderer->RegisterImage("Textures/WaterExpl.png");
|
||||
if((int) cg_particles < 2)
|
||||
color.w = .3f;
|
||||
Handle<IImage> img = renderer->RegisterImage("Textures/WaterExpl.png");
|
||||
if((int) cg_particles < 2)
|
||||
color.w = .3f;
|
||||
for(int i = 0; i < 7; i++){
|
||||
ParticleSpriteEntity *ent =
|
||||
new ParticleSpriteEntity(this, img, color);
|
||||
@ -513,12 +513,12 @@ namespace spades {
|
||||
ent->SetLifeTime(3.f + GetRandom()*0.3f, 0.f, .60f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
// water2
|
||||
img = renderer->RegisterImage("Textures/Fluid.png");
|
||||
color.w = .9f;
|
||||
if((int) cg_particles < 2)
|
||||
color.w = .4f;
|
||||
color.w = .4f;
|
||||
for(int i = 0; i < 16; i++){
|
||||
ParticleSpriteEntity *ent =
|
||||
new ParticleSpriteEntity(this, img, color);
|
||||
@ -534,11 +534,11 @@ namespace spades {
|
||||
ent->SetLifeTime(3.f + GetRandom()*0.3f, .7f, .60f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
// slow smoke
|
||||
color.w = .4f;
|
||||
if((int) cg_particles < 2)
|
||||
color.w = .2f;
|
||||
color.w = .4f;
|
||||
if((int) cg_particles < 2)
|
||||
color.w = .2f;
|
||||
for(int i = 0; i < 8; i++){
|
||||
ParticleSpriteEntity *ent =
|
||||
new SmokeSpriteEntity(this, color, 20.f);
|
||||
@ -551,20 +551,20 @@ namespace spades {
|
||||
ent->SetRadius(1.4f + GetRandom()*GetRandom()*0.8f,
|
||||
0.2f);
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
|
||||
switch ((int)cg_particles) {
|
||||
case 1:
|
||||
ent->SetLifeTime(3.f + GetRandom() * 5.f, 0.1f, 8.f);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
default:
|
||||
ent->SetLifeTime(6.f + GetRandom() * 5.f, 0.1f, 8.f);
|
||||
break;
|
||||
|
||||
}
|
||||
switch ((int)cg_particles) {
|
||||
case 1:
|
||||
ent->SetLifeTime(3.f + GetRandom() * 5.f, 0.1f, 8.f);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
default:
|
||||
ent->SetLifeTime(6.f + GetRandom() * 5.f, 0.1f, 8.f);
|
||||
break;
|
||||
|
||||
}
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
// fragments
|
||||
img = renderer->RegisterImage("Gfx/White.tga");
|
||||
color = MakeVector4(1,1,1, 0.7f);
|
||||
@ -586,22 +586,22 @@ namespace spades {
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Delete);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: wave?
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Client::BulletHitWaterSurface(spades::Vector3 origin){
|
||||
float dist = (origin - lastSceneDef.viewOrigin).GetLength();
|
||||
if(dist > 150.f)
|
||||
return;
|
||||
if(!cg_waterImpact)
|
||||
return;
|
||||
|
||||
if((int) cg_particles < 1)
|
||||
return;
|
||||
|
||||
|
||||
if((int) cg_particles < 1)
|
||||
return;
|
||||
|
||||
Vector4 color;
|
||||
color = MakeVector4( .95f, .95f, .95f, .3f);
|
||||
// water1
|
||||
@ -622,7 +622,7 @@ namespace spades {
|
||||
ent->SetLifeTime(3.f + GetRandom()*0.3f, 0.1f, .60f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
// water2
|
||||
img = renderer->RegisterImage("Textures/Fluid.png");
|
||||
color.w = .9f;
|
||||
@ -642,8 +642,8 @@ namespace spades {
|
||||
ent->SetLifeTime(3.f + GetRandom()*0.3f, GetRandom() * 0.3f, .60f);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// fragments
|
||||
img = renderer->RegisterImage("Gfx/White.tga");
|
||||
color = MakeVector4(1,1,1, 0.7f);
|
||||
@ -664,13 +664,13 @@ namespace spades {
|
||||
ent->SetBlockHitAction(ParticleSpriteEntity::Delete);
|
||||
localEntities.emplace_back(ent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: wave?
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Camera Control
|
||||
|
||||
|
||||
enum { AutoFocusPoints = 4 };
|
||||
void Client::UpdateAutoFocus(float dt) {
|
||||
if (autoFocusEnabled && world && (int)cg_manualFocus) {
|
||||
@ -681,7 +681,7 @@ namespace spades {
|
||||
const Vector3 camDir = lastSceneDef.viewAxis[2].Normalize();
|
||||
const Vector3 camX = lastSceneDef.viewAxis[0].Normalize() * measureRange;
|
||||
const Vector3 camY = lastSceneDef.viewAxis[1].Normalize() * measureRange;
|
||||
|
||||
|
||||
float distances[AutoFocusPoints * AutoFocusPoints];
|
||||
std::size_t numValidDistances = 0;
|
||||
Vector3 camDir1 = camDir - camX - camY;
|
||||
@ -691,43 +691,43 @@ namespace spades {
|
||||
Vector3 camDir2 = camDir1;
|
||||
for (int y = 0; y < AutoFocusPoints; ++y) {
|
||||
float dist = RayCastForAutoFocus(camOrigin, camDir2);
|
||||
|
||||
|
||||
dist *= lenScale;
|
||||
|
||||
|
||||
if (std::isfinite(dist) && dist > 0.8f) {
|
||||
distances[numValidDistances++] = dist;
|
||||
}
|
||||
|
||||
|
||||
camDir2 += camDY;
|
||||
}
|
||||
camDir1 += camDX;
|
||||
}
|
||||
|
||||
|
||||
if (numValidDistances > 0) {
|
||||
// Take median
|
||||
std::sort(distances, distances + numValidDistances);
|
||||
|
||||
|
||||
float dist = (numValidDistances & 1) ?
|
||||
distances[numValidDistances >> 1] :
|
||||
(distances[numValidDistances >> 1] + distances[(numValidDistances >> 1) - 1]) * 0.5f;
|
||||
|
||||
|
||||
targetFocalLength = dist;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Change the actual focal length slowly
|
||||
{
|
||||
float dist = 1.f / targetFocalLength;
|
||||
float curDist = 1.f / focalLength;
|
||||
const float maxSpeed = cg_autoFocusSpeed;
|
||||
|
||||
|
||||
if (dist > curDist) {
|
||||
curDist = std::min(dist, curDist + maxSpeed * dt);
|
||||
} else {
|
||||
curDist = std::max(dist, curDist - maxSpeed * dt);
|
||||
}
|
||||
|
||||
|
||||
focalLength = 1.f / curDist;
|
||||
}
|
||||
}
|
||||
@ -735,7 +735,7 @@ namespace spades {
|
||||
const Vector3 &direction)
|
||||
{
|
||||
SPAssert(world);
|
||||
|
||||
|
||||
const auto &lastSceneDef = this->lastSceneDef;
|
||||
World::WeaponRayCastResult result =
|
||||
world->WeaponRayCast(origin,
|
||||
@ -744,7 +744,7 @@ namespace spades {
|
||||
if (result.hit) {
|
||||
return Vector3::Dot(result.hitPos - origin, lastSceneDef.viewAxis[2]);
|
||||
}
|
||||
|
||||
|
||||
return std::nan(nullptr);
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,22 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
based on code of pysnip (c) Mathias Kaerlev 2011-2012.
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "Client.h"
|
||||
@ -53,9 +53,9 @@ static float nextRandom() {
|
||||
|
||||
namespace spades {
|
||||
namespace client {
|
||||
|
||||
|
||||
#pragma mark - Drawing
|
||||
|
||||
|
||||
bool Client::ShouldRenderInThirdPersonView() {
|
||||
if(world && world->GetLocalPlayer()){
|
||||
if(!world->GetLocalPlayer()->IsAlive())
|
||||
@ -66,7 +66,7 @@ namespace spades {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
float Client::GetLocalFireVibration() {
|
||||
float localFireVibration = 0.f;
|
||||
localFireVibration = time - localFireVibrationTime;
|
||||
@ -75,7 +75,7 @@ namespace spades {
|
||||
localFireVibration = 0.f;
|
||||
return localFireVibration;
|
||||
}
|
||||
|
||||
|
||||
float Client::GetAimDownZoomScale(){
|
||||
if(world == nullptr ||
|
||||
world->GetLocalPlayer() == nullptr ||
|
||||
@ -97,27 +97,27 @@ namespace spades {
|
||||
float aimDownState = GetAimDownState();
|
||||
return 1.f + powf(aimDownState, 5.f) * delta;
|
||||
}
|
||||
|
||||
|
||||
SceneDefinition Client::CreateSceneDefinition() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
int shakeLevel = cg_shake;
|
||||
|
||||
|
||||
int shakeLevel = cg_shake;
|
||||
|
||||
SceneDefinition def;
|
||||
def.time = (unsigned int)(time * 1000.f);
|
||||
def.denyCameraBlur = true;
|
||||
def.zFar = 200.f;
|
||||
|
||||
def.denyCameraBlur = true;
|
||||
def.zFar = 200.f;
|
||||
|
||||
if(world){
|
||||
IntVector3 fogColor = world->GetFogColor();
|
||||
renderer->SetFogColor(MakeVector3(fogColor.x / 255.f,
|
||||
fogColor.y / 255.f,
|
||||
fogColor.z / 255.f));
|
||||
|
||||
|
||||
Player *player = world->GetLocalPlayer();
|
||||
|
||||
|
||||
def.blurVignette = .0f;
|
||||
|
||||
|
||||
if(IsFollowing()){
|
||||
int limit = 100;
|
||||
// if current following player has left,
|
||||
@ -133,7 +133,7 @@ namespace spades {
|
||||
player = world->GetPlayer(followingPlayerId);
|
||||
}
|
||||
if(player){
|
||||
|
||||
|
||||
float roll = 0.f;
|
||||
float scale = 1.f;
|
||||
float vibPitch = 0.f;
|
||||
@ -143,7 +143,7 @@ namespace spades {
|
||||
Vector3 center = player->GetEye();
|
||||
Vector3 playerFront = player->GetFront2D();
|
||||
Vector3 up = MakeVector3(0,0,-1);
|
||||
|
||||
|
||||
if((!player->IsAlive()) && lastMyCorpse &&
|
||||
player == world->GetLocalPlayer()){
|
||||
center = lastMyCorpse->GetCenter();
|
||||
@ -163,7 +163,7 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float distance = 5.f;
|
||||
if(player == world->GetLocalPlayer() &&
|
||||
world->GetLocalPlayer()->GetTeamId() < 2 &&
|
||||
@ -172,14 +172,14 @@ namespace spades {
|
||||
float elapsedTime = time - lastAliveTime;
|
||||
distance -= 3.f * expf(-elapsedTime * 1.f);
|
||||
}
|
||||
|
||||
|
||||
Vector3 eye = center;
|
||||
//eye -= playerFront * 5.f;
|
||||
//eye += up * 2.0f;
|
||||
eye.x += cosf(followYaw) * cosf(followPitch) * distance;
|
||||
eye.y += sinf(followYaw) * cosf(followPitch) * distance;
|
||||
eye.z -= sinf(followPitch) * distance;
|
||||
|
||||
|
||||
if(false){
|
||||
// settings for making limbo stuff
|
||||
eye = center;
|
||||
@ -188,7 +188,7 @@ namespace spades {
|
||||
eye += player->GetRight() *2.f;
|
||||
scale *= .6f;
|
||||
}
|
||||
|
||||
|
||||
// try ray casting
|
||||
GameMap::RayCastResult result;
|
||||
result = map->CastRay2(center, (eye - center).Normalize(), 256);
|
||||
@ -201,10 +201,10 @@ namespace spades {
|
||||
eye += (center - eye).Normalize() * diff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vector3 front = center - eye;
|
||||
front = front.Normalize();
|
||||
|
||||
|
||||
if(FirstPersonSpectate == false){
|
||||
def.viewOrigin = eye;
|
||||
def.viewAxis[0] = -Vector3::Cross(up, front).Normalize();
|
||||
@ -216,100 +216,100 @@ namespace spades {
|
||||
def.viewAxis[1] = player->GetUp();
|
||||
def.viewAxis[2] = player->GetFront();
|
||||
}
|
||||
|
||||
|
||||
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
|
||||
def.fovX = atanf(tanf(def.fovY * .5f) *
|
||||
renderer->ScreenWidth() /
|
||||
renderer->ScreenHeight()) * 2.f;
|
||||
|
||||
|
||||
// update initial spectate pos
|
||||
// this is not used now, but if the local player is
|
||||
// is spectating, this is used when he/she's no
|
||||
// longer following
|
||||
followPos = def.viewOrigin;
|
||||
followVel = MakeVector3(0, 0, 0);
|
||||
|
||||
|
||||
}else if(player->GetTeamId() >= 2){
|
||||
// spectator view (noclip view)
|
||||
Vector3 center = followPos;
|
||||
Vector3 front;
|
||||
Vector3 up = {0, 0, -1};
|
||||
|
||||
|
||||
front.x = -cosf(followYaw) * cosf(followPitch);
|
||||
front.y = -sinf(followYaw) * cosf(followPitch);
|
||||
front.z = sinf(followPitch);
|
||||
|
||||
|
||||
def.viewOrigin = center;
|
||||
def.viewAxis[0] = -Vector3::Cross(up, front).Normalize();
|
||||
def.viewAxis[1] = -Vector3::Cross(front, def.viewAxis[0]).Normalize();
|
||||
def.viewAxis[2] = front;
|
||||
|
||||
|
||||
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
|
||||
def.fovX = atanf(tanf(def.fovY * .5f) *
|
||||
renderer->ScreenWidth() /
|
||||
renderer->ScreenHeight()) * 2.f;
|
||||
|
||||
|
||||
// for 1st view, camera blur can be used
|
||||
def.denyCameraBlur = false;
|
||||
|
||||
|
||||
}else{
|
||||
Vector3 front = player->GetFront();
|
||||
Vector3 right = player->GetRight();
|
||||
Vector3 up = player->GetUp();
|
||||
|
||||
if (shakeLevel >= 1) {
|
||||
float localFireVibration = GetLocalFireVibration();
|
||||
localFireVibration *= localFireVibration;
|
||||
|
||||
if(player->GetTool() == Player::ToolSpade) {
|
||||
localFireVibration *= 0.4f;
|
||||
}
|
||||
|
||||
roll += (nextRandom() - nextRandom()) * 0.03f * localFireVibration;
|
||||
scale += nextRandom() * 0.04f * localFireVibration;
|
||||
|
||||
vibPitch += localFireVibration * (1.f - localFireVibration) * 0.01f;
|
||||
vibYaw += sinf(localFireVibration * (float)M_PI * 2.f) * 0.001f;
|
||||
|
||||
def.radialBlur += localFireVibration * 0.2f;
|
||||
|
||||
// sprint bob
|
||||
{
|
||||
float sp = SmoothStep(GetSprintState());
|
||||
vibYaw += sinf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f) * 0.01f * sp;
|
||||
roll -= sinf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f) * 0.005f * (sp);
|
||||
float p = cosf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f);
|
||||
p = p * p; p *= p; p *= p; p *= p;
|
||||
vibPitch += p * 0.01f * sp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (shakeLevel >= 1) {
|
||||
float localFireVibration = GetLocalFireVibration();
|
||||
localFireVibration *= localFireVibration;
|
||||
|
||||
if(player->GetTool() == Player::ToolSpade) {
|
||||
localFireVibration *= 0.4f;
|
||||
}
|
||||
|
||||
roll += (nextRandom() - nextRandom()) * 0.03f * localFireVibration;
|
||||
scale += nextRandom() * 0.04f * localFireVibration;
|
||||
|
||||
vibPitch += localFireVibration * (1.f - localFireVibration) * 0.01f;
|
||||
vibYaw += sinf(localFireVibration * (float)M_PI * 2.f) * 0.001f;
|
||||
|
||||
def.radialBlur += localFireVibration * 0.2f;
|
||||
|
||||
// sprint bob
|
||||
{
|
||||
float sp = SmoothStep(GetSprintState());
|
||||
vibYaw += sinf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f) * 0.01f * sp;
|
||||
roll -= sinf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f) * 0.005f * (sp);
|
||||
float p = cosf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f);
|
||||
p = p * p; p *= p; p *= p; p *= p;
|
||||
vibPitch += p * 0.01f * sp;
|
||||
}
|
||||
}
|
||||
|
||||
scale /= GetAimDownZoomScale();
|
||||
|
||||
|
||||
def.viewOrigin = player->GetEye();
|
||||
def.viewAxis[0] = right;
|
||||
def.viewAxis[1] = up;
|
||||
def.viewAxis[2] = front;
|
||||
|
||||
|
||||
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
|
||||
def.fovX = atanf(tanf(def.fovY * .5f) *
|
||||
renderer->ScreenWidth() /
|
||||
renderer->ScreenHeight()) * 2.f;
|
||||
|
||||
|
||||
// for 1st view, camera blur can be used
|
||||
def.denyCameraBlur = false;
|
||||
|
||||
|
||||
float aimDownState = GetAimDownState();
|
||||
float per = aimDownState;
|
||||
per *= per * per;
|
||||
def.depthOfFieldFocalLength = per * 13.f + .054f;
|
||||
|
||||
|
||||
def.blurVignette = .0f;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// add vibration for both 1st/3rd view
|
||||
{
|
||||
// add grenade vibration
|
||||
@ -322,100 +322,100 @@ namespace spades {
|
||||
vibPitch += (nextRandom() - nextRandom()) * 0.1f * grenVib;
|
||||
vibYaw += (nextRandom() - nextRandom()) * 0.1f * grenVib;
|
||||
scale -= (nextRandom()-nextRandom()) * 0.1f * grenVib;
|
||||
|
||||
|
||||
def.radialBlur += grenVib * 0.8f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// add roll / scale
|
||||
{
|
||||
Vector3 right = def.viewAxis[0];
|
||||
Vector3 up = def.viewAxis[1];
|
||||
|
||||
|
||||
def.viewAxis[0] = right * cosf(roll) - up * sinf(roll);
|
||||
def.viewAxis[1] = up * cosf(roll) + right * sinf(roll);
|
||||
|
||||
def.fovX = atanf(tanf(def.fovX * .5f) * scale) * 2.f;
|
||||
def.fovY = atanf(tanf(def.fovY * .5f) * scale) * 2.f;
|
||||
|
||||
def.fovX = atanf(tanf(def.fovX * .5f) * scale) * 2.f;
|
||||
def.fovY = atanf(tanf(def.fovY * .5f) * scale) * 2.f;
|
||||
}
|
||||
{
|
||||
Vector3 u = def.viewAxis[1];
|
||||
Vector3 v = def.viewAxis[2];
|
||||
|
||||
|
||||
def.viewAxis[1] = u * cosf(vibPitch) - v * sinf(vibPitch);
|
||||
def.viewAxis[2] = v * cosf(vibPitch) + u * sinf(vibPitch);
|
||||
}
|
||||
{
|
||||
Vector3 u = def.viewAxis[0];
|
||||
Vector3 v = def.viewAxis[2];
|
||||
|
||||
|
||||
def.viewAxis[0] = u * cosf(vibYaw) - v * sinf(vibYaw);
|
||||
def.viewAxis[2] = v * cosf(vibYaw) + u * sinf(vibYaw);
|
||||
}
|
||||
{
|
||||
float wTime = world->GetTime();
|
||||
if(wTime < lastHurtTime + .15f &&
|
||||
wTime >= lastHurtTime){
|
||||
wTime >= lastHurtTime){
|
||||
float per = 1.f - (wTime - lastHurtTime) / .15f;
|
||||
per *= .5f - player->GetHealth() / 100.f * .3f;
|
||||
def.blurVignette += per * 6.f;
|
||||
}
|
||||
if(wTime < lastHurtTime + .2f &&
|
||||
wTime >= lastHurtTime){
|
||||
wTime >= lastHurtTime){
|
||||
float per = 1.f - (wTime - lastHurtTime) / .2f;
|
||||
per *= .5f - player->GetHealth() / 100.f * .3f;
|
||||
def.saturation *= std::max(0.f, 1.f - per * 4.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def.zNear = 0.05f;
|
||||
|
||||
|
||||
def.skipWorld = false;
|
||||
}else{
|
||||
def.viewOrigin = MakeVector3(256, 256, 4);
|
||||
def.viewAxis[0] = MakeVector3(-1, 0, 0);
|
||||
def.viewAxis[1] = MakeVector3(0, 1, 0);
|
||||
def.viewAxis[2] = MakeVector3(0, 0, 1);
|
||||
|
||||
|
||||
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
|
||||
def.fovX = atanf(tanf(def.fovY * .5f) *
|
||||
renderer->ScreenWidth() /
|
||||
renderer->ScreenHeight()) * 2.f;
|
||||
|
||||
|
||||
def.zNear = 0.05f;
|
||||
|
||||
|
||||
def.skipWorld = false;
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
def.viewOrigin = MakeVector3(0, 0, 0);
|
||||
def.viewAxis[0] = MakeVector3(1, 0, 0);
|
||||
def.viewAxis[1] = MakeVector3(0, 0, -1);
|
||||
def.viewAxis[2] = MakeVector3(0, 0, 1);
|
||||
|
||||
|
||||
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
|
||||
def.fovX = atanf(tanf(def.fovY * .5f) *
|
||||
renderer->ScreenWidth() /
|
||||
renderer->ScreenHeight()) * 2.f;
|
||||
|
||||
|
||||
def.zNear = 0.05f;
|
||||
|
||||
|
||||
def.skipWorld = true;
|
||||
|
||||
|
||||
renderer->SetFogColor(MakeVector3(0,0,0));
|
||||
}
|
||||
|
||||
if (def.viewOrigin.z < 0.f) {
|
||||
// Need to move the far plane because there's no vertical fog
|
||||
def.zFar -= def.viewOrigin.z;
|
||||
}
|
||||
|
||||
|
||||
if (def.viewOrigin.z < 0.f) {
|
||||
// Need to move the far plane because there's no vertical fog
|
||||
def.zFar -= def.viewOrigin.z;
|
||||
}
|
||||
|
||||
SPAssert(!isnan(def.viewOrigin.x));
|
||||
SPAssert(!isnan(def.viewOrigin.y));
|
||||
SPAssert(!isnan(def.viewOrigin.z));
|
||||
|
||||
|
||||
def.radialBlur = std::min(def.radialBlur, 1.f);
|
||||
|
||||
|
||||
if ((int)cg_manualFocus) {
|
||||
// Depth of field is manually controlled
|
||||
def.depthOfFieldNearBlurStrength = def.depthOfFieldFarBlurStrength =
|
||||
@ -425,29 +425,29 @@ namespace spades {
|
||||
def.depthOfFieldNearBlurStrength = cg_depthOfFieldAmount;
|
||||
def.depthOfFieldFarBlurStrength = 0.f;
|
||||
}
|
||||
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
void Client::AddGrenadeToScene(spades::client::Grenade *g) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
IModel *model;
|
||||
model = renderer->RegisterModel("Models/Weapons/Grenade/Grenade.kv6");
|
||||
|
||||
|
||||
if(g->GetPosition().z > 63.f) {
|
||||
// work-around for water refraction problem
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ModelRenderParam param;
|
||||
Matrix4 mat = Matrix4::Scale(0.03f);
|
||||
mat = Matrix4::Translate(g->GetPosition()) * mat;
|
||||
param.matrix = mat;
|
||||
|
||||
|
||||
renderer->RenderModel(model, param);
|
||||
}
|
||||
|
||||
|
||||
void Client::AddDebugObjectToScene(const spades::OBB3 &obb, const Vector4& color) {
|
||||
const Matrix4& mat = obb.m;
|
||||
Vector3 v[2][2][2];
|
||||
@ -459,23 +459,23 @@ namespace spades {
|
||||
v[1][0][1] = (mat * MakeVector3(1,0,1)).GetXYZ();
|
||||
v[1][1][0] = (mat * MakeVector3(1,1,0)).GetXYZ();
|
||||
v[1][1][1] = (mat * MakeVector3(1,1,1)).GetXYZ();
|
||||
|
||||
|
||||
renderer->AddDebugLine(v[0][0][0], v[1][0][0], color);
|
||||
renderer->AddDebugLine(v[0][0][1], v[1][0][1], color);
|
||||
renderer->AddDebugLine(v[0][1][0], v[1][1][0], color);
|
||||
renderer->AddDebugLine(v[0][1][1], v[1][1][1], color);
|
||||
|
||||
|
||||
renderer->AddDebugLine(v[0][0][0], v[0][1][0], color);
|
||||
renderer->AddDebugLine(v[0][0][1], v[0][1][1], color);
|
||||
renderer->AddDebugLine(v[1][0][0], v[1][1][0], color);
|
||||
renderer->AddDebugLine(v[1][0][1], v[1][1][1], color);
|
||||
|
||||
|
||||
renderer->AddDebugLine(v[0][0][0], v[0][0][1], color);
|
||||
renderer->AddDebugLine(v[0][1][0], v[0][1][1], color);
|
||||
renderer->AddDebugLine(v[1][0][0], v[1][0][1], color);
|
||||
renderer->AddDebugLine(v[1][1][0], v[1][1][1], color);
|
||||
}
|
||||
|
||||
|
||||
void Client::DrawCTFObjects() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
CTFGameMode *mode = static_cast<CTFGameMode *>(world->GetMode());
|
||||
@ -488,15 +488,15 @@ namespace spades {
|
||||
Vector3 color = {
|
||||
col.x / 255.f, col.y / 255.f, col.z / 255.f
|
||||
};
|
||||
|
||||
|
||||
ModelRenderParam param;
|
||||
param.customColor = color;
|
||||
|
||||
|
||||
// draw base
|
||||
param.matrix = Matrix4::Translate(team.basePos);
|
||||
param.matrix = param.matrix * Matrix4::Scale(.3f);
|
||||
renderer->RenderModel(base, param);
|
||||
|
||||
|
||||
// draw flag
|
||||
if(!mode->GetTeam(1-tId).hasIntel){
|
||||
param.matrix = Matrix4::Translate(team.flagPos);
|
||||
@ -505,7 +505,7 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::DrawTCObjects() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
TCGameMode *mode = static_cast<TCGameMode *>(world->GetMode());
|
||||
@ -523,26 +523,26 @@ namespace spades {
|
||||
Vector3 color = {
|
||||
col.x / 255.f, col.y / 255.f, col.z / 255.f
|
||||
};
|
||||
|
||||
|
||||
ModelRenderParam param;
|
||||
param.customColor = color;
|
||||
|
||||
|
||||
// draw base
|
||||
param.matrix = Matrix4::Translate(t->pos);
|
||||
param.matrix = param.matrix * Matrix4::Scale(.3f);
|
||||
renderer->RenderModel(base, param);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::DrawScene(){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
renderer->StartScene(lastSceneDef);
|
||||
|
||||
|
||||
if(world){
|
||||
Player *p = world->GetLocalPlayer();
|
||||
|
||||
|
||||
for(size_t i = 0; i < world->GetNumPlayerSlots(); i++)
|
||||
if(world->GetPlayer(static_cast<unsigned int>(i))){
|
||||
SPAssert(clientPlayers[i]);
|
||||
@ -552,7 +552,7 @@ namespace spades {
|
||||
for(size_t i = 0; i < nades.size(); i++){
|
||||
AddGrenadeToScene(nades[i]);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
for(auto& c: corpses){
|
||||
Vector3 center = c->GetCenter();
|
||||
@ -561,19 +561,19 @@ namespace spades {
|
||||
c->AddToScene();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( IGameMode::m_CTF == world->GetMode()->ModeType() ){
|
||||
DrawCTFObjects();
|
||||
} else if( IGameMode::m_TC == world->GetMode()->ModeType() ){
|
||||
DrawTCObjects();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
for(auto& ent: localEntities){
|
||||
ent->Render3D();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// draw block cursor
|
||||
// FIXME: don't use debug line
|
||||
if(p){
|
||||
@ -589,9 +589,9 @@ namespace spades {
|
||||
}else{
|
||||
blocks.push_back(p->GetBlockCursorPos());
|
||||
}
|
||||
|
||||
|
||||
bool active = p->IsBlockCursorActive();
|
||||
|
||||
|
||||
Vector4 color = {1,1,1,1};
|
||||
if(!active)
|
||||
color = Vector4(1,1,0,1);
|
||||
@ -599,12 +599,12 @@ namespace spades {
|
||||
color = MakeVector4(1,0,0,1);
|
||||
if(!active)
|
||||
color.w *= 0.5f;
|
||||
|
||||
|
||||
for(size_t i = 0; i < blocks.size(); i++){
|
||||
IntVector3& v = blocks[i];
|
||||
|
||||
|
||||
if(active) {
|
||||
|
||||
|
||||
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
|
||||
MakeVector3(v.x+1, v.y, v.z),
|
||||
color);
|
||||
@ -620,7 +620,7 @@ namespace spades {
|
||||
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
|
||||
MakeVector3(v.x+1, v.y, v.z),
|
||||
color);
|
||||
|
||||
|
||||
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
|
||||
MakeVector3(v.x, v.y+1, v.z),
|
||||
color);
|
||||
@ -633,7 +633,7 @@ namespace spades {
|
||||
renderer->AddDebugLine(MakeVector3(v.x+1, v.y, v.z+1),
|
||||
MakeVector3(v.x+1, v.y+1, v.z+1),
|
||||
color);
|
||||
|
||||
|
||||
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
|
||||
MakeVector3(v.x, v.y, v.z+1),
|
||||
color);
|
||||
@ -648,7 +648,7 @@ namespace spades {
|
||||
color);
|
||||
}else{
|
||||
// not active
|
||||
|
||||
|
||||
const float ln = 0.1f;
|
||||
{
|
||||
float xx = v.x, yy = v.y, zz = v.z;
|
||||
@ -698,20 +698,20 @@ namespace spades {
|
||||
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy-ln, zz), color);
|
||||
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz-ln), color);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// --- one block drawn
|
||||
} // end for
|
||||
|
||||
|
||||
} // p->IsReadyToUseTool
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(size_t i = 0; i < flashDlights.size(); i++)
|
||||
renderer->AddLight(flashDlights[i]);
|
||||
flashDlightsOld.clear();
|
||||
flashDlightsOld.swap(flashDlights);
|
||||
|
||||
|
||||
// draw player hottrack
|
||||
// FIXME: don't use debug line
|
||||
{
|
||||
@ -721,7 +721,7 @@ namespace spades {
|
||||
IntVector3 col = world->GetTeam(hottracked->GetTeamId()).color;
|
||||
Vector4 color = Vector4::Make( col.x / 255.f, col.y / 255.f, col.z / 255.f, 1.f );
|
||||
Vector4 color2 = Vector4::Make( 1, 1, 1, 1);
|
||||
|
||||
|
||||
Player::HitBoxes hb = hottracked->GetHitBoxes();
|
||||
AddDebugObjectToScene(hb.head, (tag & hit_Head) ? color2 : color );
|
||||
AddDebugObjectToScene(hb.torso, (tag & hit_Torso) ? color2 : color );
|
||||
@ -730,29 +730,29 @@ namespace spades {
|
||||
AddDebugObjectToScene(hb.limbs[2], (tag & hit_Arms) ? color2 : color );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
renderer->EndScene();
|
||||
}
|
||||
|
||||
|
||||
Vector3 Client::Project(spades::Vector3 v){
|
||||
v -= lastSceneDef.viewOrigin;
|
||||
|
||||
|
||||
// transform to NDC
|
||||
Vector3 v2;
|
||||
v2.x = Vector3::Dot(v, lastSceneDef.viewAxis[0]);
|
||||
v2.y = Vector3::Dot(v, lastSceneDef.viewAxis[1]);
|
||||
v2.z = Vector3::Dot(v, lastSceneDef.viewAxis[2]);
|
||||
|
||||
|
||||
float tanX = tanf(lastSceneDef.fovX * .5f);
|
||||
float tanY = tanf(lastSceneDef.fovY * .5f);
|
||||
|
||||
|
||||
v2.x /= tanX * v2.z;
|
||||
v2.y /= tanY * v2.z;
|
||||
|
||||
|
||||
// transform to IRenderer 2D coord
|
||||
v2.x = (v2.x + 1.f) / 2.f * renderer->ScreenWidth();
|
||||
v2.y = (-v2.y + 1.f) / 2.f * renderer->ScreenHeight();
|
||||
|
||||
|
||||
return v2;
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "Corpse.h"
|
||||
@ -38,29 +38,29 @@ namespace spades {
|
||||
Player *p):
|
||||
renderer(renderer), map(map) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
IntVector3 col = p->GetWorld()->GetTeam(p->GetTeamId()).color;
|
||||
color = MakeVector3(col.x / 255.f,
|
||||
col.y / 255.f,
|
||||
col.z / 255.f);
|
||||
|
||||
|
||||
bool crouch = p->GetInput().crouch;
|
||||
Vector3 front = p->GetFront();
|
||||
|
||||
|
||||
float yaw = atan2(front.y, front.x) + static_cast<float>(M_PI) * .5f;
|
||||
//float pitch = -atan2(front.z, sqrt(front.x * front.x + front.y * front.y));
|
||||
|
||||
|
||||
// lower axis
|
||||
Matrix4 lower = Matrix4::Translate(p->GetOrigin());
|
||||
lower = lower * Matrix4::Rotate(MakeVector3(0,0,1),
|
||||
yaw);
|
||||
|
||||
|
||||
Matrix4 torso;
|
||||
|
||||
|
||||
if(crouch){
|
||||
lower = lower * Matrix4::Translate(0, 0, -0.4f);
|
||||
torso = lower * Matrix4::Translate(0, 0, -0.3f);
|
||||
|
||||
|
||||
SetNode(Torso1,
|
||||
torso*MakeVector3(0.4f, -.15f, 0.1f));
|
||||
SetNode(Torso2,
|
||||
@ -69,20 +69,20 @@ namespace spades {
|
||||
torso*MakeVector3(-0.4f, .8f, 0.7f));
|
||||
SetNode(Torso4,
|
||||
torso*MakeVector3(0.4f, .8f, 0.7f));
|
||||
|
||||
|
||||
SetNode(Leg1,
|
||||
lower*MakeVector3(-0.4f, .1f, 1.f));
|
||||
SetNode(Leg2,
|
||||
lower*MakeVector3(0.4f, .1f, 1.f));
|
||||
|
||||
|
||||
SetNode(Arm1,
|
||||
torso*MakeVector3(0.2f, -.4f, .2f));
|
||||
SetNode(Arm2,
|
||||
torso*MakeVector3(-0.2f, -.4f, .2f));
|
||||
|
||||
|
||||
}else{
|
||||
torso = lower * Matrix4::Translate(0, 0, -1.1f);
|
||||
|
||||
|
||||
SetNode(Torso1,
|
||||
torso*MakeVector3(0.4f, 0.f, 0.1f));
|
||||
SetNode(Torso2,
|
||||
@ -91,29 +91,29 @@ namespace spades {
|
||||
torso*MakeVector3(-0.4f, .0f, 1.f));
|
||||
SetNode(Torso4,
|
||||
torso*MakeVector3(0.4f, .0f, 1.f));
|
||||
|
||||
|
||||
SetNode(Leg1,
|
||||
lower*MakeVector3(-0.4f, .0f, 1.f));
|
||||
SetNode(Leg2,
|
||||
lower*MakeVector3(0.4f, .0f, 1.f));
|
||||
|
||||
|
||||
SetNode(Arm1,
|
||||
torso*MakeVector3(0.2f, -.4f, .2f));
|
||||
SetNode(Arm2,
|
||||
torso*MakeVector3(-0.2f, -.4f, .2f));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
SetNode(Head, (nodes[Torso1].pos + nodes[Torso2].pos)
|
||||
* .5f + MakeVector3(0,0,-0.6f));
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static float VelNoise() {
|
||||
return (GetRandom() - GetRandom()) * 2.f;
|
||||
}
|
||||
|
||||
|
||||
void Corpse::SetNode(NodeType n, spades::Vector3 v){
|
||||
SPAssert(n >= 0); SPAssert(n < NodeCount);
|
||||
nodes[n].pos = v;
|
||||
@ -122,16 +122,16 @@ namespace spades {
|
||||
0.f);
|
||||
nodes[n].lastPos = v;
|
||||
nodes[n].lastForce = MakeVector3(0, 0,0);
|
||||
|
||||
|
||||
}
|
||||
void Corpse::SetNode(NodeType n, spades::Vector4 v){
|
||||
SetNode(n, v.GetXYZ());
|
||||
}
|
||||
|
||||
|
||||
Corpse::~Corpse(){
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Corpse::Spring(NodeType n1,
|
||||
NodeType n2,
|
||||
float distance,
|
||||
@ -145,18 +145,18 @@ namespace spades {
|
||||
float dist = diff.GetLength();
|
||||
Vector3 force = diff.Normalize() * (distance - dist);
|
||||
force *= dt * 50.f;
|
||||
|
||||
|
||||
b.vel += force;
|
||||
a.vel -= force;
|
||||
|
||||
|
||||
b.pos += force / (dt * 50.f) * 0.5f;
|
||||
a.pos -= force / (dt * 50.f) * 0.5f;
|
||||
|
||||
|
||||
Vector3 velMid = (a.vel + b.vel) * .5f;
|
||||
float dump = 1.f - powf(.1f, dt);
|
||||
a.vel += (velMid - a.vel) * dump;
|
||||
b.vel += (velMid - b.vel) * dump;
|
||||
|
||||
|
||||
}
|
||||
void Corpse::Spring(NodeType n1a,
|
||||
NodeType n1b,
|
||||
@ -174,20 +174,20 @@ namespace spades {
|
||||
float dist = diff.GetLength();
|
||||
Vector3 force = diff.Normalize() * (distance - dist);
|
||||
force *= dt * 50.f;
|
||||
|
||||
|
||||
b.vel += force;
|
||||
force *= .5f;
|
||||
x.vel -= force;
|
||||
y.vel -= force;
|
||||
|
||||
|
||||
Vector3 velMid = (x.vel + y.vel) * .25f + b.vel * .5f;
|
||||
float dump = 1.f - powf(.05f, dt);
|
||||
x.vel += (velMid - x.vel) * dump;
|
||||
y.vel += (velMid - y.vel) * dump;
|
||||
b.vel += (velMid - b.vel) * dump;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static float MyACos(float v){
|
||||
SPAssert(!isnan(v));
|
||||
if(v >= 1.f) return 0.f;
|
||||
@ -214,48 +214,48 @@ namespace spades {
|
||||
float ln1 = d1.GetLength();
|
||||
float ln2 = d2.GetLength();
|
||||
float dot = Vector3::Dot(d1, d2) / (ln1 * ln2 + 0.0000001f);
|
||||
|
||||
|
||||
if(dot >= minDot && dot <= maxDot)
|
||||
return;
|
||||
|
||||
|
||||
Vector3 diff = n2.pos - n1.pos;
|
||||
float strength = 0.f;
|
||||
|
||||
|
||||
Vector3 a1 = Vector3::Cross(d1, diff);
|
||||
a1 = Vector3::Cross(d1, a1).Normalize();
|
||||
|
||||
|
||||
Vector3 a2 = Vector3::Cross(d2, diff);
|
||||
a2 = Vector3::Cross(d2, a2).Normalize();
|
||||
|
||||
|
||||
//a1=-a1; a2=-a2;
|
||||
//a1 = -a1;
|
||||
a2 = -a2;
|
||||
|
||||
|
||||
if(dot > maxDot){
|
||||
strength = MyACos(dot) - MyACos(maxDot);
|
||||
}else if(dot < minDot){
|
||||
strength = MyACos(dot) - MyACos(minDot);
|
||||
}
|
||||
|
||||
|
||||
SPAssert(!isnan(strength));
|
||||
|
||||
|
||||
strength *= 20.f;
|
||||
strength *= dt;
|
||||
|
||||
|
||||
a1 *= strength;
|
||||
a2 *= strength;
|
||||
|
||||
|
||||
a2 *= 0.f;
|
||||
|
||||
|
||||
n2.vel += a1;
|
||||
n1.vel += a2;
|
||||
nBase.vel -= a1 + a2;
|
||||
|
||||
|
||||
/*
|
||||
d1 += a1 * 0.01;
|
||||
d2 += a2 * 0.01;
|
||||
float nd = Vector3::Dot(d1, d2) / (d1.GetLength() * d2.GetLength());
|
||||
|
||||
|
||||
if(dot > maxDot){
|
||||
if(nd < dot)
|
||||
printf("GOOD %f -> %f\n", dot, nd);
|
||||
@ -279,42 +279,42 @@ namespace spades {
|
||||
Vector3 diff = n2.pos - n1.pos;
|
||||
float ln1 = diff.GetLength();
|
||||
float dot = Vector3::Dot(diff, dir) / (ln1 + 0.000000001f);
|
||||
|
||||
|
||||
if(dot >= minDot && dot <= maxDot)
|
||||
return;
|
||||
|
||||
|
||||
float strength = 0.f;
|
||||
|
||||
|
||||
Vector3 a1 = Vector3::Cross(dir, diff);
|
||||
a1 = Vector3::Cross(diff, a1).Normalize();
|
||||
|
||||
|
||||
Vector3 a2 = -a1;
|
||||
//a1=-a1; a2=-a2;
|
||||
//a1 = -a1;
|
||||
|
||||
|
||||
if(dot > maxDot){
|
||||
strength = MyACos(dot) - MyACos(maxDot);
|
||||
}else if(dot < minDot){
|
||||
strength = MyACos(dot) - MyACos(minDot);
|
||||
}
|
||||
|
||||
|
||||
SPAssert(!isnan(strength));
|
||||
|
||||
|
||||
strength *= 100.f;
|
||||
strength *= dt;
|
||||
|
||||
|
||||
a1 *= strength;
|
||||
a2 *= strength;
|
||||
|
||||
|
||||
n2.vel += a1;
|
||||
n1.vel += a2;
|
||||
//nBase.vel -= a1 + a2;
|
||||
|
||||
|
||||
/*
|
||||
d1 += a1 * 0.01;
|
||||
d2 += a2 * 0.01;
|
||||
float nd = Vector3::Dot(d1, d2) / (d1.GetLength() * d2.GetLength());
|
||||
|
||||
|
||||
if(dot > maxDot){
|
||||
if(nd < dot)
|
||||
printf("GOOD %f -> %f\n", dot, nd);
|
||||
@ -327,11 +327,11 @@ namespace spades {
|
||||
printf("BAD %f -> %f\n", dot, nd);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
static float fractf(float v){
|
||||
return v - floorf(v);
|
||||
}
|
||||
|
||||
|
||||
static void CheckEscape(GameMap *map,
|
||||
IntVector3 hitBlock,
|
||||
IntVector3 a, IntVector3 b,
|
||||
@ -370,31 +370,31 @@ namespace spades {
|
||||
SPAssert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(dist < bestDist){
|
||||
bestDist = dist;
|
||||
bestDir = dir;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Corpse::LineCollision(NodeType a, NodeType b, float dt){
|
||||
if(!r_corpseLineCollision)
|
||||
return;
|
||||
Node& n1 = nodes[a];
|
||||
Node& n2 = nodes[b];
|
||||
|
||||
|
||||
IntVector3 hitBlock;
|
||||
|
||||
|
||||
if(map->CastRay(n1.lastPos, n2.lastPos, 16.f, hitBlock)) {
|
||||
GameMap::RayCastResult res1 = map->CastRay2(n1.lastPos, n2.lastPos - n1.lastPos, 8);
|
||||
GameMap::RayCastResult res2 = map->CastRay2(n2.lastPos, n1.lastPos - n2.lastPos, 8);
|
||||
|
||||
|
||||
if(!res1.hit) return;
|
||||
if(!res2.hit) return;
|
||||
if(res1.startSolid || res2.startSolid){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// really hit?
|
||||
if(Vector3::Dot(res1.hitPos - n1.lastPos, n2.lastPos - n1.lastPos)
|
||||
> (n2.pos-n1.pos).GetPoweredLength()){
|
||||
@ -412,23 +412,23 @@ namespace spades {
|
||||
< 0.f){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Vector3 blockPos;
|
||||
blockPos.x = hitBlock.x + .5f;
|
||||
blockPos.y = hitBlock.y + .5f;
|
||||
blockPos.z = hitBlock.z + .5f;
|
||||
|
||||
|
||||
float inlen = (res1.hitPos - res2.hitPos).GetLength();
|
||||
|
||||
|
||||
IntVector3 ivec = {0, 0, 0};
|
||||
|
||||
|
||||
ivec.x += res1.normal.x;
|
||||
ivec.y += res1.normal.y;
|
||||
ivec.z += res1.normal.z;
|
||||
ivec.x += res2.normal.x;
|
||||
ivec.y += res2.normal.y;
|
||||
ivec.z += res2.normal.z;
|
||||
|
||||
|
||||
Vector3 dir = {0.f, 0.f, 0.f};
|
||||
if(ivec.x == 0 && ivec.y == 0 && ivec.z == 0) {
|
||||
// hanging. which direction to escape?
|
||||
@ -474,25 +474,25 @@ namespace spades {
|
||||
dir.x = ivec.x;
|
||||
dir.y = ivec.y;
|
||||
dir.z = ivec.z;
|
||||
|
||||
|
||||
Vector3 normDir = dir; // |D|
|
||||
|
||||
|
||||
n1.vel -= normDir * std::min(Vector3::Dot(normDir, n1.vel), 0.f);
|
||||
n2.vel -= normDir * std::min(Vector3::Dot(normDir, n2.vel), 0.f);
|
||||
|
||||
|
||||
dir *= dt * inlen * 5.f;
|
||||
|
||||
|
||||
n1.vel += dir;
|
||||
n2.vel += dir;
|
||||
|
||||
|
||||
// friction
|
||||
n1.vel -= (n1.vel - normDir * Vector3::Dot(normDir, n1.vel)) * .2f;
|
||||
n2.vel -= (n2.vel - normDir * Vector3::Dot(normDir, n2.vel)) * .2f;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Corpse::AngularMomentum(int eId,
|
||||
NodeType a,
|
||||
NodeType b){
|
||||
@ -503,19 +503,19 @@ namespace spades {
|
||||
e.node1 = a; e.node2 = b;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Vector3 force = e.lastVelDiff - e.velDiff;
|
||||
force *= .5f;
|
||||
nodes[b].vel += force;
|
||||
nodes[a].vel -= force;
|
||||
|
||||
|
||||
e.lastVelDiff = e.velDiff;
|
||||
}
|
||||
|
||||
void Corpse::ApplyConstraint(float dt) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
|
||||
|
||||
AngularMomentum(0,
|
||||
Torso1, Torso2);
|
||||
AngularMomentum(1,
|
||||
@ -532,23 +532,23 @@ namespace spades {
|
||||
Torso3, Leg1);
|
||||
AngularMomentum(7,
|
||||
Torso4, Leg2);
|
||||
|
||||
|
||||
Spring(Torso1, Torso2,
|
||||
0.8f, dt);
|
||||
Spring(Torso3, Torso4,
|
||||
0.8f, dt);
|
||||
|
||||
|
||||
Spring(Torso1, Torso4,
|
||||
0.9f, dt);
|
||||
Spring(Torso2, Torso3,
|
||||
0.9f, dt);
|
||||
|
||||
|
||||
Spring(Torso1, Torso3,
|
||||
1.204f, dt);
|
||||
Spring(Torso2, Torso4,
|
||||
1.204f, dt);
|
||||
|
||||
|
||||
|
||||
|
||||
Spring(Arm1, Torso1,
|
||||
1.f, dt);
|
||||
Spring(Arm2, Torso2,
|
||||
@ -557,33 +557,33 @@ namespace spades {
|
||||
1.f, dt);
|
||||
Spring(Leg2, Torso4,
|
||||
1.f, dt);
|
||||
|
||||
|
||||
AngleSpring(Torso1,
|
||||
Arm1, Torso3,
|
||||
-1.f, 0.6f, dt);
|
||||
AngleSpring(Torso2,
|
||||
Arm2, Torso4,
|
||||
-1.f, 0.6f, dt);
|
||||
|
||||
|
||||
AngleSpring(Torso3,
|
||||
Leg1, Torso2,
|
||||
-1.f, -0.2f, dt);
|
||||
AngleSpring(Torso4,
|
||||
Leg2, Torso1,
|
||||
-1.f, -0.2f, dt);
|
||||
|
||||
|
||||
Spring(Torso1, Torso2, Head,
|
||||
.6f, dt);
|
||||
/*
|
||||
AngleSpring(Torso1,
|
||||
Torso2, Head,
|
||||
0.5f, 1.f, dt);
|
||||
|
||||
|
||||
AngleSpring(Torso2,
|
||||
Torso1, Head,
|
||||
0.5f, 1.f, dt);
|
||||
*/
|
||||
|
||||
|
||||
LineCollision(Torso1, Torso2, dt);
|
||||
LineCollision(Torso2, Torso3, dt);
|
||||
LineCollision(Torso3, Torso4, dt);
|
||||
@ -594,57 +594,57 @@ namespace spades {
|
||||
LineCollision(Torso2, Arm2, dt);
|
||||
LineCollision(Torso3, Leg1, dt);
|
||||
LineCollision(Torso4, Leg2, dt);
|
||||
|
||||
|
||||
|
||||
|
||||
return;
|
||||
AngleSpring(Torso4,
|
||||
Torso1, Head,
|
||||
0.5f, 1.f, dt);
|
||||
|
||||
|
||||
AngleSpring(Torso3,
|
||||
Torso2, Head,
|
||||
0.5f, 1.f, dt);
|
||||
|
||||
|
||||
AngleSpring(Torso4,
|
||||
Torso2, Head,
|
||||
0.5f, 1.f, dt);
|
||||
|
||||
|
||||
AngleSpring(Torso3,
|
||||
Torso1, Head,
|
||||
0.5f, 1.f, dt);
|
||||
}
|
||||
|
||||
|
||||
void Corpse::Update(float dt) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
float damp = 1.f;
|
||||
float damp2 = 1.f;
|
||||
float damp2 = 1.f;
|
||||
if(dt > 0.f){
|
||||
damp = powf(.9f, dt);
|
||||
damp2 = powf(.371f, dt);
|
||||
}
|
||||
}
|
||||
//dt *= 0.1f;
|
||||
|
||||
|
||||
for(int i = 0; i <NodeCount; i++){
|
||||
Node& node = nodes[i];
|
||||
Vector3 oldPos = node.lastPos;
|
||||
node.pos += node.vel * dt;
|
||||
|
||||
|
||||
SPAssert(!isnan(node.pos.x));
|
||||
SPAssert(!isnan(node.pos.y));
|
||||
SPAssert(!isnan(node.pos.z));
|
||||
|
||||
|
||||
if(node.pos.z > 63.f){
|
||||
node.vel.z -= dt * 6.f; // buoyancy
|
||||
node.vel *= damp;
|
||||
}else{
|
||||
node.vel.z += dt * 32.f; // gravity
|
||||
node.vel.z *= damp2;
|
||||
}
|
||||
|
||||
node.vel.z += dt * 32.f; // gravity
|
||||
node.vel.z *= damp2;
|
||||
}
|
||||
|
||||
//node.vel *= damp;
|
||||
|
||||
|
||||
if(!map->ClipBox(oldPos.x, oldPos.y, oldPos.z)){
|
||||
|
||||
|
||||
if(map->ClipBox(node.pos.x,
|
||||
oldPos.y,
|
||||
oldPos.z)){
|
||||
@ -652,11 +652,11 @@ namespace spades {
|
||||
if(fabsf(node.vel.x) < .3f)
|
||||
node.vel.x = 0.f;
|
||||
node.pos.x = oldPos.x;
|
||||
|
||||
|
||||
node.vel.y *= .5f;
|
||||
node.vel.z *= .5f;
|
||||
}
|
||||
|
||||
|
||||
if(map->ClipBox(node.pos.x,
|
||||
node.pos.y,
|
||||
oldPos.z)){
|
||||
@ -664,11 +664,11 @@ namespace spades {
|
||||
if(fabsf(node.vel.y) < .3f)
|
||||
node.vel.y = 0.f;
|
||||
node.pos.y = oldPos.y;
|
||||
|
||||
|
||||
node.vel.x *= .5f;
|
||||
node.vel.z *= .5f;
|
||||
}
|
||||
|
||||
|
||||
if(map->ClipBox(node.pos.x,
|
||||
node.pos.y,
|
||||
node.pos.z)){
|
||||
@ -676,18 +676,18 @@ namespace spades {
|
||||
if(fabsf(node.vel.z) < .3f)
|
||||
node.vel.z = 0.f;
|
||||
node.pos.z = oldPos.z;
|
||||
|
||||
|
||||
node.vel.x *= .5f;
|
||||
node.vel.y *= .5f;
|
||||
}
|
||||
|
||||
|
||||
if(map->ClipBox(node.pos.x, node.pos.y, node.pos.z)){
|
||||
// TODO: getting out block
|
||||
//node.pos = oldPos;
|
||||
//node.vel *= .5f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if(map->ClipBox(node.pos.x,
|
||||
node.pos.y,
|
||||
@ -718,23 +718,23 @@ namespace spades {
|
||||
}
|
||||
node.vel *= .8f;
|
||||
//node.pos = oldPos;
|
||||
|
||||
|
||||
if(node.vel.GetLength() < .02f){
|
||||
node.vel *= 0.f;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
node.lastPos = node.pos;
|
||||
node.lastForce = node.vel;
|
||||
}
|
||||
ApplyConstraint(dt);
|
||||
|
||||
|
||||
for(int i = 0; i <NodeCount; i++){
|
||||
nodes[i].lastForce = nodes[i].vel - nodes[i].lastForce;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Corpse::AddToScene() {
|
||||
if(false){
|
||||
// debug line only
|
||||
@ -751,42 +751,42 @@ namespace spades {
|
||||
renderer->AddDebugLine(nodes[Torso4].pos,
|
||||
nodes[Torso1].pos,
|
||||
col);
|
||||
|
||||
|
||||
renderer->AddDebugLine(nodes[Torso2].pos,
|
||||
nodes[Torso4].pos,
|
||||
col);
|
||||
renderer->AddDebugLine(nodes[Torso1].pos,
|
||||
nodes[Torso3].pos,
|
||||
col);
|
||||
|
||||
|
||||
|
||||
|
||||
renderer->AddDebugLine(nodes[Torso1].pos,
|
||||
nodes[Arm1].pos,
|
||||
col);
|
||||
renderer->AddDebugLine(nodes[Torso2].pos,
|
||||
nodes[Arm2].pos,
|
||||
col);
|
||||
|
||||
|
||||
renderer->AddDebugLine(nodes[Torso3].pos,
|
||||
nodes[Leg1].pos,
|
||||
col);
|
||||
renderer->AddDebugLine(nodes[Torso4].pos,
|
||||
nodes[Leg2].pos,
|
||||
col);
|
||||
|
||||
|
||||
|
||||
|
||||
renderer->AddDebugLine((nodes[Torso1].pos+nodes[Torso2].pos)*.5f,
|
||||
nodes[Head].pos,
|
||||
col);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ModelRenderParam param;
|
||||
param.customColor = color;
|
||||
|
||||
|
||||
IModel *model;
|
||||
Matrix4 scaler = Matrix4::Scale(.1f);
|
||||
|
||||
|
||||
// draw torso
|
||||
Matrix4 torso;
|
||||
Vector3 tX, tY;
|
||||
@ -801,9 +801,9 @@ namespace spades {
|
||||
tY = Vector3::Cross(tX, tZ).Normalize();
|
||||
Vector3 tOrigin = tY1 * .5f;
|
||||
torso = Matrix4::FromAxis(tX, -tZ, -tY, tOrigin);
|
||||
|
||||
|
||||
param.matrix = torso * scaler;
|
||||
|
||||
|
||||
model = renderer->RegisterModel
|
||||
("Models/Player/Torso.kv6");
|
||||
renderer->RenderModel(model, param);
|
||||
@ -812,13 +812,13 @@ namespace spades {
|
||||
{
|
||||
Vector3 headBase =
|
||||
(torso * MakeVector3(0.0f, 0.f, 0.f)).GetXYZ();
|
||||
|
||||
|
||||
model = renderer->RegisterModel
|
||||
("Models/Player/Head.kv6");
|
||||
|
||||
|
||||
Vector3 aX, aY, aZ;
|
||||
Vector3 center = (nodes[Torso1].pos + nodes[Torso2].pos) * .5f;
|
||||
|
||||
|
||||
aZ = nodes[Head].pos - center;
|
||||
aZ = -torso.GetAxis(2);
|
||||
aZ = aZ.Normalize();
|
||||
@ -826,73 +826,73 @@ namespace spades {
|
||||
aY = Vector3::Cross(aY, aZ).Normalize();
|
||||
aX = Vector3::Cross(aY, aZ).Normalize();
|
||||
param.matrix = Matrix4::FromAxis(-aX, aY, -aZ, headBase) * scaler;
|
||||
|
||||
|
||||
renderer->RenderModel(model, param);
|
||||
}
|
||||
|
||||
|
||||
// draw Arms
|
||||
{
|
||||
Vector3 arm1Base =
|
||||
(torso * MakeVector3(0.4f, 0.f, 0.2f)).GetXYZ();
|
||||
Vector3 arm2Base =
|
||||
(torso * MakeVector3(-0.4f, 0.f, 0.2f)).GetXYZ();
|
||||
|
||||
|
||||
model = renderer->RegisterModel
|
||||
("Models/Player/Arm.kv6");
|
||||
|
||||
|
||||
Vector3 aX, aY, aZ;
|
||||
|
||||
|
||||
aZ = nodes[Arm1].pos - nodes[Torso1].pos;
|
||||
aZ = aZ.Normalize();
|
||||
aY = nodes[Torso2].pos - nodes[Torso1].pos;
|
||||
aY = Vector3::Cross(aY, aZ).Normalize();
|
||||
aX = Vector3::Cross(aY, aZ).Normalize();
|
||||
param.matrix = Matrix4::FromAxis(aX, aY, aZ, arm1Base) * scaler;
|
||||
|
||||
|
||||
renderer->RenderModel(model, param);
|
||||
|
||||
|
||||
aZ = nodes[Arm2].pos - nodes[Torso2].pos;
|
||||
aZ = aZ.Normalize();
|
||||
aY = nodes[Torso1].pos - nodes[Torso2].pos;
|
||||
aY = Vector3::Cross(aY, aZ).Normalize();
|
||||
aX = Vector3::Cross(aY, aZ).Normalize();
|
||||
param.matrix = Matrix4::FromAxis(aX, aY, aZ, arm2Base) * scaler;
|
||||
|
||||
|
||||
renderer->RenderModel(model, param);
|
||||
}
|
||||
|
||||
|
||||
// draw Leg
|
||||
{
|
||||
Vector3 leg1Base =
|
||||
(torso * MakeVector3(0.25f, 0.f, 0.9f)).GetXYZ();
|
||||
Vector3 leg2Base =
|
||||
(torso * MakeVector3(-0.25f, 0.f, 0.9f)).GetXYZ();
|
||||
|
||||
|
||||
model = renderer->RegisterModel
|
||||
("Models/Player/Leg.kv6");
|
||||
|
||||
|
||||
Vector3 aX, aY, aZ;
|
||||
|
||||
|
||||
aZ = nodes[Leg1].pos - nodes[Torso3].pos;
|
||||
aZ = aZ.Normalize();
|
||||
aY = nodes[Torso1].pos - nodes[Torso2].pos;
|
||||
aY = Vector3::Cross(aY, aZ).Normalize();
|
||||
aX = Vector3::Cross(aY, aZ).Normalize();
|
||||
param.matrix = Matrix4::FromAxis(aX, aY, aZ, leg1Base) * scaler;
|
||||
|
||||
|
||||
renderer->RenderModel(model, param);
|
||||
|
||||
|
||||
aZ = nodes[Leg2].pos - nodes[Torso4].pos;
|
||||
aZ = aZ.Normalize();
|
||||
aY = nodes[Torso1].pos - nodes[Torso2].pos;
|
||||
aY = Vector3::Cross(aY, aZ).Normalize();
|
||||
aX = Vector3::Cross(aY, aZ).Normalize();
|
||||
param.matrix = Matrix4::FromAxis(aX, aY, aZ, leg2Base) * scaler;
|
||||
|
||||
|
||||
renderer->RenderModel(model, param);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vector3 Corpse::GetCenter() {
|
||||
Vector3 v = {0,0,0};
|
||||
for(int i = 0; i < NodeCount; i++)
|
||||
@ -900,12 +900,12 @@ namespace spades {
|
||||
v *= 1.f / (float)NodeCount;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
bool Corpse::IsVisibleFrom(spades::Vector3 eye){
|
||||
// distance culled?
|
||||
if((eye - GetCenter()).GetLength() > 150.f)
|
||||
return false;
|
||||
|
||||
|
||||
for(int i = 0; i < NodeCount; i++){
|
||||
IntVector3 outBlk;
|
||||
if(map->CastRay(eye, nodes[i].pos,
|
||||
@ -914,7 +914,7 @@ namespace spades {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Corpse::AddImpulse(spades::Vector3 v){
|
||||
for(int i = 0; i < NodeCount; i++)
|
||||
nodes[i].vel += v;
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "GameMapWrapper.h"
|
||||
@ -31,51 +31,51 @@
|
||||
|
||||
namespace spades {
|
||||
namespace client {
|
||||
|
||||
|
||||
|
||||
|
||||
GameMapWrapper::GameMapWrapper(GameMap *mp):
|
||||
map(mp) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
width = mp->Width();
|
||||
height = mp->Height();
|
||||
depth = mp->Depth();
|
||||
linkMap = new uint8_t[width*height*depth];
|
||||
memset(linkMap, 0, width * height * depth);
|
||||
}
|
||||
|
||||
|
||||
GameMapWrapper::~GameMapWrapper() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
delete[] linkMap;
|
||||
}
|
||||
|
||||
|
||||
void GameMapWrapper::Rebuild() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
Stopwatch stopwatch;
|
||||
|
||||
|
||||
GameMap *m = map;
|
||||
memset(linkMap, 0, width * height * depth);
|
||||
|
||||
|
||||
for(int x = 0; x < width; x++)
|
||||
for(int y = 0; y < height; y++)
|
||||
SetLink(x, y, depth - 1, Root);
|
||||
|
||||
|
||||
Deque<CellPos> queue(width * height * 2);
|
||||
|
||||
|
||||
for(int x = 0; x < width; x++)
|
||||
for(int y = 0; y < height; y++)
|
||||
if(m->IsSolid(x, y, depth - 2)){
|
||||
SetLink(x, y, depth-2, PositiveZ);
|
||||
queue.Push(CellPos(x, y, depth - 2));
|
||||
}
|
||||
|
||||
|
||||
while(!queue.IsEmpty()){
|
||||
CellPos p = queue.Front();
|
||||
queue.Shift();
|
||||
|
||||
|
||||
int x = p.x, y = p.y, z = p.z;
|
||||
|
||||
|
||||
if(p.x > 0 && m->IsSolid(x-1,y,z) && GetLink(x-1,y,z) == Invalid){
|
||||
SetLink(x-1, y, z, PositiveX);
|
||||
queue.Push(CellPos(x-1, y, z));
|
||||
@ -101,28 +101,28 @@ namespace spades {
|
||||
queue.Push(CellPos(x, y, z+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SPLog("%.3f msecs to rebuild",
|
||||
stopwatch.GetTime() * 1000.);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GameMapWrapper::AddBlock(int x, int y, int z, uint32_t color){
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
GameMap *m = map;
|
||||
|
||||
|
||||
if(GetLink(x, y, z) != Invalid) {
|
||||
SPAssert(m->IsSolid(x, y, z));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m->Set(x, y, z, true, color);
|
||||
|
||||
|
||||
if(GetLink(x, y, z) != Invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LinkType l = Invalid;
|
||||
if(x > 0 && m->IsSolid(x - 1, y, z) &&
|
||||
GetLink(x-1, y, z) != Invalid){
|
||||
@ -155,7 +155,7 @@ namespace spades {
|
||||
SPAssert(GetLink(x, y, z+1) != NegativeZ);
|
||||
}
|
||||
SetLink(x, y, z, l);
|
||||
|
||||
|
||||
if(l == Invalid)
|
||||
return;
|
||||
// if there's invalid block around this block,
|
||||
@ -165,12 +165,12 @@ namespace spades {
|
||||
while(!queue.IsEmpty()){
|
||||
CellPos p = queue.Front();
|
||||
queue.Shift();
|
||||
|
||||
|
||||
int x = p.x, y = p.y, z = p.z;
|
||||
SPAssert(m->IsSolid(x,y,z));
|
||||
|
||||
|
||||
LinkType thisLink = GetLink(x, y, z);
|
||||
|
||||
|
||||
if(p.x > 0 && m->IsSolid(x-1,y,z) && GetLink(x-1,y,z) == Invalid &&
|
||||
thisLink != NegativeX){
|
||||
SetLink(x-1, y, z, PositiveX);
|
||||
@ -202,50 +202,50 @@ namespace spades {
|
||||
queue.Push(CellPos(x, y, z+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline bool EqualTwoCond(T a, T b, T c, bool cond) {
|
||||
return a == b || (cond && a == c);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static inline bool EqualTwoCond(T a, T b, T c, bool cond) {
|
||||
return a == b || (cond && a == c);
|
||||
}
|
||||
|
||||
std::vector<CellPos> GameMapWrapper::RemoveBlocks(const std::vector<CellPos>& cells) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
if(cells.empty())
|
||||
return std::vector<CellPos>();
|
||||
|
||||
|
||||
GameMap *m = map;
|
||||
|
||||
|
||||
// solid, but unlinked cells
|
||||
std::vector<CellPos> unlinkedCells;
|
||||
Deque<CellPos> queue(1024);
|
||||
|
||||
|
||||
// unlink children
|
||||
for(size_t i = 0; i < cells.size(); i++){
|
||||
CellPos pos = cells[i];
|
||||
m->Set(pos.x, pos.y, pos.z, false, 0);
|
||||
// if(GetLink(pos.x, pos.y, pos.z) == Invalid){
|
||||
// this block is already disconnected.
|
||||
// }
|
||||
|
||||
if(GetLink(pos.x, pos.y, pos.z) == Marked){
|
||||
continue;
|
||||
}
|
||||
// this block is already disconnected.
|
||||
// }
|
||||
|
||||
if(GetLink(pos.x, pos.y, pos.z) == Marked){
|
||||
continue;
|
||||
}
|
||||
SPAssert(GetLink(pos.x, pos.y, pos.z) != Root);
|
||||
|
||||
|
||||
SetLink(pos.x, pos.y, pos.z, Invalid);
|
||||
queue.Push(pos);
|
||||
|
||||
|
||||
while(!queue.IsEmpty()){
|
||||
pos = queue.Front();
|
||||
queue.Shift();
|
||||
|
||||
|
||||
if(m->IsSolid(pos.x, pos.y, pos.z))
|
||||
unlinkedCells.push_back(pos);
|
||||
// don't "continue;" when non-solid
|
||||
|
||||
|
||||
int x = pos.x, y = pos.y, z = pos.z;
|
||||
if(x > 0 && EqualTwoCond(GetLink(x-1,y,z), PositiveX, Invalid, m->IsSolid(x-1, y, z))){
|
||||
SetLink(x-1, y, z, Marked);
|
||||
@ -272,18 +272,18 @@ namespace spades {
|
||||
queue.Push(CellPos(x, y, z+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// remove "visited" mark
|
||||
|
||||
// remove "visited" mark
|
||||
for(size_t i = 0; i < unlinkedCells.size(); i++){
|
||||
const CellPos& pos = unlinkedCells[i];
|
||||
if(GetLink(pos.x, pos.y, pos.z) == Marked)
|
||||
SetLink(pos.x, pos.y, pos.z, Invalid);
|
||||
}
|
||||
|
||||
const CellPos& pos = unlinkedCells[i];
|
||||
if(GetLink(pos.x, pos.y, pos.z) == Marked)
|
||||
SetLink(pos.x, pos.y, pos.z, Invalid);
|
||||
}
|
||||
|
||||
SPAssert(queue.IsEmpty());
|
||||
|
||||
|
||||
// start relinking
|
||||
for(size_t i = 0; i < unlinkedCells.size(); i++){
|
||||
const CellPos& pos = unlinkedCells[i];
|
||||
@ -293,7 +293,7 @@ namespace spades {
|
||||
// don't use SPAssert()
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
LinkType newLink = Invalid;
|
||||
if(z < depth - 1 && GetLink(x,y,z+1) != Invalid){
|
||||
newLink = PositiveZ;
|
||||
@ -308,21 +308,21 @@ namespace spades {
|
||||
}else if(z > 0 && GetLink(x,y,z-1) != Invalid){
|
||||
newLink = NegativeZ;
|
||||
}
|
||||
|
||||
|
||||
if(newLink != Invalid){
|
||||
SetLink(x, y, z, newLink);
|
||||
queue.Push(pos);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
while(!queue.IsEmpty()){
|
||||
CellPos p = queue.Front();
|
||||
queue.Shift();
|
||||
|
||||
|
||||
int x = p.x, y = p.y, z = p.z;
|
||||
LinkType thisLink = GetLink(x,y,z);
|
||||
|
||||
|
||||
if(p.x > 0 && m->IsSolid(x-1,y,z) && GetLink(x-1,y,z) == Invalid &&
|
||||
thisLink != NegativeX){
|
||||
SetLink(x-1, y, z, PositiveX);
|
||||
@ -354,10 +354,10 @@ namespace spades {
|
||||
queue.Push(CellPos(x, y, z+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<CellPos> floatingBlocks;
|
||||
floatingBlocks.reserve(unlinkedCells.size());
|
||||
|
||||
|
||||
for(size_t i = 0; i < unlinkedCells.size(); i++){
|
||||
const CellPos& p = unlinkedCells[i];
|
||||
if(!m->IsSolid(p.x, p.y, p.z))
|
||||
@ -366,7 +366,7 @@ namespace spades {
|
||||
floatingBlocks.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return floatingBlocks;
|
||||
}
|
||||
}
|
||||
|
@ -37,115 +37,115 @@ namespace spades {
|
||||
#endif
|
||||
};
|
||||
|
||||
MumbleLink::MumbleLink() :
|
||||
metre_per_block(0.63),
|
||||
MumbleLink::MumbleLink() :
|
||||
metre_per_block(0.63),
|
||||
mumbleLinkedMemory(nullptr),
|
||||
priv(new MumbleLinkPrivate())
|
||||
{}
|
||||
|
||||
MumbleLink::~MumbleLink() {
|
||||
#ifdef WIN32
|
||||
UnmapViewOfFile(mumbleLinkedMemory);
|
||||
if (priv->obj != nullptr)
|
||||
CloseHandle(priv->obj);
|
||||
#else
|
||||
munmap(mumbleLinkedMemory, sizeof(*mumbleLinkedMemory));
|
||||
if (priv->fd > 0)
|
||||
close(priv->fd);
|
||||
#endif
|
||||
}
|
||||
MumbleLink::~MumbleLink() {
|
||||
#ifdef WIN32
|
||||
UnmapViewOfFile(mumbleLinkedMemory);
|
||||
if (priv->obj != nullptr)
|
||||
CloseHandle(priv->obj);
|
||||
#else
|
||||
munmap(mumbleLinkedMemory, sizeof(*mumbleLinkedMemory));
|
||||
if (priv->fd > 0)
|
||||
close(priv->fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MumbleLink::set_mumble_vector3(float mumble_vec[3],
|
||||
const spades::Vector3 &vec) {
|
||||
mumble_vec[0] = vec.x;
|
||||
mumble_vec[1] = vec.z;
|
||||
mumble_vec[2] = vec.y;
|
||||
}
|
||||
void MumbleLink::set_mumble_vector3(float mumble_vec[3],
|
||||
const spades::Vector3 &vec) {
|
||||
mumble_vec[0] = vec.x;
|
||||
mumble_vec[1] = vec.z;
|
||||
mumble_vec[2] = vec.y;
|
||||
}
|
||||
|
||||
bool MumbleLink::init() {
|
||||
assert(mumbleLinkedMemory == nullptr);
|
||||
#ifdef WIN32
|
||||
priv->obj = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
|
||||
if (priv->obj == nullptr)
|
||||
return false;
|
||||
bool MumbleLink::init() {
|
||||
assert(mumbleLinkedMemory == nullptr);
|
||||
#ifdef WIN32
|
||||
priv->obj = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
|
||||
if (priv->obj == nullptr)
|
||||
return false;
|
||||
|
||||
mumbleLinkedMemory = static_cast<MumbleLinkedMemory *>(MapViewOfFile(
|
||||
priv->obj, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumbleLinkedMemory)));
|
||||
mumbleLinkedMemory = static_cast<MumbleLinkedMemory *>(MapViewOfFile(
|
||||
priv->obj, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumbleLinkedMemory)));
|
||||
|
||||
if (mumbleLinkedMemory == nullptr) {
|
||||
CloseHandle(priv->obj);
|
||||
priv->obj = nullptr;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
std::string name = "/MumbleLink." + std::to_string(getuid());
|
||||
if (mumbleLinkedMemory == nullptr) {
|
||||
CloseHandle(priv->obj);
|
||||
priv->obj = nullptr;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
std::string name = "/MumbleLink." + std::to_string(getuid());
|
||||
|
||||
priv->fd = shm_open(name.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
|
||||
priv->fd = shm_open(name.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
|
||||
|
||||
if (priv->fd < 0) {
|
||||
return false;
|
||||
}
|
||||
if (priv->fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mumbleLinkedMemory = static_cast<MumbleLinkedMemory *>(
|
||||
(mmap(nullptr, sizeof(*mumbleLinkedMemory), PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, priv->fd, 0)));
|
||||
mumbleLinkedMemory = static_cast<MumbleLinkedMemory *>(
|
||||
(mmap(nullptr, sizeof(*mumbleLinkedMemory), PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, priv->fd, 0)));
|
||||
|
||||
if (mumbleLinkedMemory == MAP_FAILED) {
|
||||
mumbleLinkedMemory = nullptr;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
if (mumbleLinkedMemory == MAP_FAILED) {
|
||||
mumbleLinkedMemory = nullptr;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void MumbleLink::setContext(const std::string &context) {
|
||||
if (mumbleLinkedMemory == nullptr)
|
||||
return;
|
||||
size_t len(std::min(256, static_cast<int>(context.size())));
|
||||
std::memcpy(mumbleLinkedMemory->context, context.c_str(), len);
|
||||
mumbleLinkedMemory->context_len = len;
|
||||
}
|
||||
void MumbleLink::setContext(const std::string &context) {
|
||||
if (mumbleLinkedMemory == nullptr)
|
||||
return;
|
||||
size_t len(std::min(256, static_cast<int>(context.size())));
|
||||
std::memcpy(mumbleLinkedMemory->context, context.c_str(), len);
|
||||
mumbleLinkedMemory->context_len = len;
|
||||
}
|
||||
|
||||
void MumbleLink::setIdentity(const std::string &identity) {
|
||||
if (mumbleLinkedMemory == nullptr)
|
||||
return;
|
||||
std::wcsncpy(mumbleLinkedMemory->identity,
|
||||
std::wstring(identity.begin(), identity.end()).c_str(), 256);
|
||||
}
|
||||
void MumbleLink::setIdentity(const std::string &identity) {
|
||||
if (mumbleLinkedMemory == nullptr)
|
||||
return;
|
||||
std::wcsncpy(mumbleLinkedMemory->identity,
|
||||
std::wstring(identity.begin(), identity.end()).c_str(), 256);
|
||||
}
|
||||
|
||||
void MumbleLink::update(spades::client::Player *player) {
|
||||
if (mumbleLinkedMemory == nullptr || player == nullptr)
|
||||
return;
|
||||
void MumbleLink::update(spades::client::Player *player) {
|
||||
if (mumbleLinkedMemory == nullptr || player == nullptr)
|
||||
return;
|
||||
|
||||
if (mumbleLinkedMemory->uiVersion != 2) {
|
||||
wcsncpy(mumbleLinkedMemory->name, L"OpenSpades", 256);
|
||||
wcsncpy(mumbleLinkedMemory->description, L"OpenSpades Link plugin.", 2048);
|
||||
mumbleLinkedMemory->uiVersion = 2;
|
||||
}
|
||||
mumbleLinkedMemory->uiTick++;
|
||||
if (mumbleLinkedMemory->uiVersion != 2) {
|
||||
wcsncpy(mumbleLinkedMemory->name, L"OpenSpades", 256);
|
||||
wcsncpy(mumbleLinkedMemory->description, L"OpenSpades Link plugin.", 2048);
|
||||
mumbleLinkedMemory->uiVersion = 2;
|
||||
}
|
||||
mumbleLinkedMemory->uiTick++;
|
||||
|
||||
// Left handed coordinate system.
|
||||
// X positive towards "right".
|
||||
// Y positive towards "up".
|
||||
// Z positive towards "front".
|
||||
//
|
||||
// 1 unit = 1 meter
|
||||
// Left handed coordinate system.
|
||||
// X positive towards "right".
|
||||
// Y positive towards "up".
|
||||
// Z positive towards "front".
|
||||
//
|
||||
// 1 unit = 1 meter
|
||||
|
||||
// Unit vector pointing out of the avatar's eyes aka "At"-vector.
|
||||
set_mumble_vector3(mumbleLinkedMemory->fAvatarFront, player->GetFront());
|
||||
// Unit vector pointing out of the avatar's eyes aka "At"-vector.
|
||||
set_mumble_vector3(mumbleLinkedMemory->fAvatarFront, player->GetFront());
|
||||
|
||||
// Unit vector pointing out of the top of the avatar's head aka "Up"-vector
|
||||
// (here Top points straight up).
|
||||
set_mumble_vector3(mumbleLinkedMemory->fAvatarTop, player->GetUp());
|
||||
// Unit vector pointing out of the top of the avatar's head aka "Up"-vector
|
||||
// (here Top points straight up).
|
||||
set_mumble_vector3(mumbleLinkedMemory->fAvatarTop, player->GetUp());
|
||||
|
||||
// Position of the avatar (here standing slightly off the origin)
|
||||
set_mumble_vector3(mumbleLinkedMemory->fAvatarPosition,
|
||||
player->GetPosition() * metre_per_block);
|
||||
// Position of the avatar (here standing slightly off the origin)
|
||||
set_mumble_vector3(mumbleLinkedMemory->fAvatarPosition,
|
||||
player->GetPosition() * metre_per_block);
|
||||
|
||||
// Same as avatar but for the camera.
|
||||
set_mumble_vector3(mumbleLinkedMemory->fCameraPosition,
|
||||
player->GetPosition() * metre_per_block);
|
||||
set_mumble_vector3(mumbleLinkedMemory->fCameraFront, player->GetFront());
|
||||
set_mumble_vector3(mumbleLinkedMemory->fCameraTop, player->GetUp());
|
||||
}
|
||||
// Same as avatar but for the camera.
|
||||
set_mumble_vector3(mumbleLinkedMemory->fCameraPosition,
|
||||
player->GetPosition() * metre_per_block);
|
||||
set_mumble_vector3(mumbleLinkedMemory->fCameraFront, player->GetFront());
|
||||
set_mumble_vector3(mumbleLinkedMemory->fCameraTop, player->GetUp());
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <OpenSpades.h>
|
||||
@ -50,39 +50,39 @@ DEFINE_SPADES_SETTING(core_numDispatchQueueThreads, "auto");
|
||||
|
||||
static int GetNumCores() {
|
||||
#ifdef WIN32
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
return sysinfo.dwNumberOfProcessors;
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
return sysinfo.dwNumberOfProcessors;
|
||||
#elif defined(__APPLE__)
|
||||
int nm[2];
|
||||
size_t len = 4;
|
||||
uint32_t count;
|
||||
|
||||
nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
|
||||
sysctl(nm, 2, &count, &len, NULL, 0);
|
||||
|
||||
if(count < 1) {
|
||||
nm[1] = HW_NCPU;
|
||||
sysctl(nm, 2, &count, &len, NULL, 0);
|
||||
if(count < 1) { count = 1; }
|
||||
}
|
||||
return count;
|
||||
int nm[2];
|
||||
size_t len = 4;
|
||||
uint32_t count;
|
||||
|
||||
nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
|
||||
sysctl(nm, 2, &count, &len, NULL, 0);
|
||||
|
||||
if(count < 1) {
|
||||
nm[1] = HW_NCPU;
|
||||
sysctl(nm, 2, &count, &len, NULL, 0);
|
||||
if(count < 1) { count = 1; }
|
||||
}
|
||||
return count;
|
||||
#elif defined(__linux__)
|
||||
return get_nprocs();
|
||||
return get_nprocs();
|
||||
#else
|
||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace spades {
|
||||
|
||||
|
||||
struct SyncQueueEntry{
|
||||
SDL_cond *doneCond;
|
||||
SDL_mutex *doneMutex;
|
||||
ConcurrentDispatch *dispatch;
|
||||
volatile bool done;
|
||||
volatile bool released;
|
||||
|
||||
|
||||
SyncQueueEntry(ConcurrentDispatch *disp):
|
||||
doneCond(SDL_CreateCond()),
|
||||
doneMutex(SDL_CreateMutex()),
|
||||
@ -98,7 +98,7 @@ namespace spades {
|
||||
delete dispatch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Done() {
|
||||
SDL_LockMutex(doneMutex);
|
||||
done = true;
|
||||
@ -109,7 +109,7 @@ namespace spades {
|
||||
}
|
||||
SDL_UnlockMutex(doneMutex);
|
||||
}
|
||||
|
||||
|
||||
void Release() {
|
||||
SDL_LockMutex(doneMutex);
|
||||
released = true;
|
||||
@ -119,7 +119,7 @@ namespace spades {
|
||||
}
|
||||
SDL_UnlockMutex(doneMutex);
|
||||
}
|
||||
|
||||
|
||||
void Join(){
|
||||
SDL_LockMutex(doneMutex);
|
||||
while(!done){
|
||||
@ -128,10 +128,10 @@ namespace spades {
|
||||
SDL_UnlockMutex(doneMutex);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class SynchronizedQueue {
|
||||
std::list<SyncQueueEntry *> entries;
|
||||
|
||||
|
||||
SDL_cond *pushCond;
|
||||
SDL_mutex *pushMutex;
|
||||
public:
|
||||
@ -143,7 +143,7 @@ namespace spades {
|
||||
SDL_DestroyMutex(pushMutex);
|
||||
SDL_DestroyCond(pushCond);
|
||||
}
|
||||
|
||||
|
||||
void Push(SyncQueueEntry * entry) {
|
||||
SDL_LockMutex(pushMutex);
|
||||
try{
|
||||
@ -155,20 +155,20 @@ namespace spades {
|
||||
SDL_CondSignal(pushCond);
|
||||
SDL_UnlockMutex(pushMutex);
|
||||
}
|
||||
|
||||
|
||||
SyncQueueEntry *Wait() {
|
||||
SDL_LockMutex(pushMutex);
|
||||
while(entries.empty()){
|
||||
SDL_CondWait(pushCond, pushMutex);
|
||||
}
|
||||
|
||||
|
||||
SyncQueueEntry *ent = entries.front();
|
||||
entries.pop_front();
|
||||
SDL_UnlockMutex(pushMutex);
|
||||
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
|
||||
SyncQueueEntry *Poll(){
|
||||
SDL_LockMutex(pushMutex);
|
||||
if(!entries.empty()){
|
||||
@ -181,11 +181,11 @@ namespace spades {
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static SynchronizedQueue globalQueue;
|
||||
static AutoDeletedThreadLocalStorage<DispatchQueue> threadQueue("threadDispatchQueue");
|
||||
static DispatchQueue *sdlQueue = NULL;
|
||||
|
||||
|
||||
DispatchQueue::DispatchQueue(){
|
||||
SPADES_MARK_FUNCTION();
|
||||
internal = new SynchronizedQueue();
|
||||
@ -194,7 +194,7 @@ namespace spades {
|
||||
SPADES_MARK_FUNCTION();
|
||||
delete internal;
|
||||
}
|
||||
|
||||
|
||||
DispatchQueue *DispatchQueue::GetThreadQueue() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
DispatchQueue *q = threadQueue;
|
||||
@ -204,7 +204,7 @@ namespace spades {
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
void DispatchQueue::ProcessQueue() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
SyncQueueEntry *ent;
|
||||
@ -213,19 +213,19 @@ namespace spades {
|
||||
}
|
||||
Thread::CleanupExitedThreads();
|
||||
}
|
||||
|
||||
|
||||
void DispatchQueue::EnterEventLoop() throw() {
|
||||
while(true){
|
||||
SyncQueueEntry *ent = internal->Wait();
|
||||
ent->dispatch->ExecuteProtected();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DispatchQueue::MarkSDLVideoThread() {
|
||||
sdlQueue = this;
|
||||
}
|
||||
|
||||
|
||||
class DispatchThread: public Thread{
|
||||
public:
|
||||
virtual void Run() throw() {
|
||||
@ -236,9 +236,9 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static std::vector<DispatchThread *> threads;
|
||||
|
||||
|
||||
ConcurrentDispatch::ConcurrentDispatch():
|
||||
entry(NULL), runnable(NULL){
|
||||
SPADES_MARK_FUNCTION();
|
||||
@ -247,12 +247,12 @@ namespace spades {
|
||||
entry(NULL),name(name), runnable(NULL){
|
||||
SPADES_MARK_FUNCTION();
|
||||
}
|
||||
|
||||
|
||||
ConcurrentDispatch::~ConcurrentDispatch(){
|
||||
SPADES_MARK_FUNCTION();
|
||||
Join();
|
||||
}
|
||||
|
||||
|
||||
void ConcurrentDispatch::Execute() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
SyncQueueEntry *ent = entry;
|
||||
@ -267,7 +267,7 @@ namespace spades {
|
||||
}
|
||||
ent->Done();
|
||||
}
|
||||
|
||||
|
||||
void ConcurrentDispatch::ExecuteProtected() throw() {
|
||||
try{
|
||||
Execute();
|
||||
@ -279,7 +279,7 @@ namespace spades {
|
||||
fprintf(stderr, "(no information provided)\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConcurrentDispatch::Start() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(entry){
|
||||
@ -302,7 +302,7 @@ namespace spades {
|
||||
globalQueue.Push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConcurrentDispatch::StartOn(DispatchQueue *queue) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(entry){
|
||||
@ -310,7 +310,7 @@ namespace spades {
|
||||
}else{
|
||||
entry = new SyncQueueEntry(this);
|
||||
queue->internal->Push(entry);
|
||||
|
||||
|
||||
if(queue == sdlQueue) {
|
||||
SDL_Event evt;
|
||||
memset(&evt, 0, sizeof(evt));
|
||||
@ -319,7 +319,7 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConcurrentDispatch::Join() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(!entry){
|
||||
@ -329,7 +329,7 @@ namespace spades {
|
||||
entry = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConcurrentDispatch::Release(){
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(entry){
|
||||
@ -337,7 +337,7 @@ namespace spades {
|
||||
ent->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConcurrentDispatch::Run(){
|
||||
if(runnable)
|
||||
runnable->Run();
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "FileManager.h"
|
||||
@ -32,20 +32,20 @@ namespace spades {
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(!fn) SPInvalidArgument("fn");
|
||||
if(fn[0] == 0) SPFileNotFound(fn);
|
||||
|
||||
// check each file systems
|
||||
|
||||
// check each file systems
|
||||
for(auto *fs: g_fileSystems){
|
||||
if(fs->FileExists(fn))
|
||||
return fs->OpenForReading(fn);
|
||||
}
|
||||
|
||||
// check weak files, too
|
||||
auto weak_fn = std::string(fn) + ".weak";
|
||||
for(auto *fs: g_fileSystems){
|
||||
if(fs->FileExists(weak_fn.c_str()))
|
||||
return fs->OpenForReading(weak_fn.c_str());
|
||||
}
|
||||
|
||||
|
||||
// check weak files, too
|
||||
auto weak_fn = std::string(fn) + ".weak";
|
||||
for(auto *fs: g_fileSystems){
|
||||
if(fs->FileExists(weak_fn.c_str()))
|
||||
return fs->OpenForReading(weak_fn.c_str());
|
||||
}
|
||||
|
||||
SPFileNotFound(fn);
|
||||
}
|
||||
IStream *FileManager::OpenForWriting(const char *fn) {
|
||||
@ -56,9 +56,9 @@ namespace spades {
|
||||
if(fs->FileExists(fn))
|
||||
return fs->OpenForWriting(fn);
|
||||
}
|
||||
|
||||
// FIXME: handling of weak files
|
||||
|
||||
|
||||
// FIXME: handling of weak files
|
||||
|
||||
// create file
|
||||
for(auto *fs: g_fileSystems){
|
||||
try{
|
||||
@ -66,50 +66,50 @@ namespace spades {
|
||||
}catch(...){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SPRaise("No filesystem is writable");
|
||||
}
|
||||
bool FileManager::FileExists(const char *fn) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(!fn) SPInvalidArgument("fn");
|
||||
|
||||
|
||||
for(auto *fs: g_fileSystems){
|
||||
if(fs->FileExists(fn))
|
||||
return true;
|
||||
}
|
||||
|
||||
// check weak files, too
|
||||
auto weak_fn = std::string(fn) + ".weak";
|
||||
for(auto *fs: g_fileSystems){
|
||||
if(fs->FileExists(weak_fn.c_str()))
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check weak files, too
|
||||
auto weak_fn = std::string(fn) + ".weak";
|
||||
for(auto *fs: g_fileSystems){
|
||||
if(fs->FileExists(weak_fn.c_str()))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void FileManager::AddFileSystem(spades::IFileSystem *fs){
|
||||
SPADES_MARK_FUNCTION();
|
||||
AppendFileSystem(fs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FileManager::AppendFileSystem(spades::IFileSystem *fs){
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(!fs) SPInvalidArgument("fs");
|
||||
|
||||
|
||||
g_fileSystems.push_back(fs);
|
||||
}
|
||||
void FileManager::PrependFileSystem(spades::IFileSystem *fs){
|
||||
SPADES_MARK_FUNCTION();
|
||||
if(!fs) SPInvalidArgument("fs");
|
||||
|
||||
|
||||
g_fileSystems.push_front(fs);
|
||||
}
|
||||
|
||||
|
||||
std::string FileManager::ReadAllBytes(const char *fn) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
|
||||
IStream *stream = OpenForReading(fn);
|
||||
try{
|
||||
std::string ret = stream->ReadAllBytes();
|
||||
@ -120,23 +120,23 @@ namespace spades {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> FileManager::EnumFiles(const char *path) {
|
||||
std::vector<std::string> list;
|
||||
std::set<std::string> set;
|
||||
if(!path) SPInvalidArgument("path");
|
||||
|
||||
|
||||
for(auto *fs: g_fileSystems){
|
||||
std::vector<std::string> l = fs->EnumFiles(path);
|
||||
for(size_t i = 0; i < l.size(); i++)
|
||||
set.insert(l[i]);
|
||||
}
|
||||
|
||||
|
||||
for(auto& s: set)
|
||||
list.push_back(s);
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "ScriptManager.h"
|
||||
@ -25,28 +25,28 @@
|
||||
#include <unordered_map>
|
||||
|
||||
namespace spades {
|
||||
|
||||
namespace
|
||||
{
|
||||
ThreadLocalStorage<bool> writeAllowed;
|
||||
|
||||
// SettingItemDescriptor supplied to ItemHandle must have the static storage duration
|
||||
std::unordered_map<std::string, const SettingItemDescriptor *>
|
||||
settingItemDescriptors;
|
||||
|
||||
const SettingItemDescriptor *MakeSettingItemDescriptor
|
||||
(const std::string &name, const std::string &defaultValue)
|
||||
{
|
||||
auto it = settingItemDescriptors.find(name);
|
||||
if (it != settingItemDescriptors.end()) {
|
||||
return it->second;
|
||||
}
|
||||
auto *descriptor = new SettingItemDescriptor(defaultValue, SettingItemFlags::None);
|
||||
settingItemDescriptors.insert(make_pair(name, descriptor));
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
ThreadLocalStorage<bool> writeAllowed;
|
||||
|
||||
// SettingItemDescriptor supplied to ItemHandle must have the static storage duration
|
||||
std::unordered_map<std::string, const SettingItemDescriptor *>
|
||||
settingItemDescriptors;
|
||||
|
||||
const SettingItemDescriptor *MakeSettingItemDescriptor
|
||||
(const std::string &name, const std::string &defaultValue)
|
||||
{
|
||||
auto it = settingItemDescriptors.find(name);
|
||||
if (it != settingItemDescriptors.end()) {
|
||||
return it->second;
|
||||
}
|
||||
auto *descriptor = new SettingItemDescriptor(defaultValue, SettingItemFlags::None);
|
||||
settingItemDescriptors.insert(make_pair(name, descriptor));
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
void MaskConfigUpdateByScript(bool disabled)
|
||||
{
|
||||
if (!writeAllowed) {
|
||||
@ -54,32 +54,32 @@ namespace spades {
|
||||
}
|
||||
*writeAllowed = !disabled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class ConfigRegistrar: public ScriptObjectRegistrar {
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
ConfigRegistrar():
|
||||
ScriptObjectRegistrar("Config") {}
|
||||
|
||||
|
||||
class ConfigItem: public RefCountedObject {
|
||||
Settings::ItemHandle handle;
|
||||
public:
|
||||
ConfigItem(const std::string& name, const std::string& defaultValue):
|
||||
handle(name, MakeSettingItemDescriptor(name, defaultValue)){
|
||||
}
|
||||
ConfigItem(const std::string& name):
|
||||
handle(name, nullptr){
|
||||
}
|
||||
|
||||
public:
|
||||
ConfigItem(const std::string& name, const std::string& defaultValue):
|
||||
handle(name, MakeSettingItemDescriptor(name, defaultValue)){
|
||||
}
|
||||
ConfigItem(const std::string& name):
|
||||
handle(name, nullptr){
|
||||
}
|
||||
|
||||
static ConfigItem *Construct(const std::string& name, const std::string& defaultValue) {
|
||||
return new ConfigItem(name, defaultValue);
|
||||
}
|
||||
static ConfigItem *Construct(const std::string& name) {
|
||||
return new ConfigItem(name);
|
||||
}
|
||||
|
||||
|
||||
ConfigItem *operator =(float fv) {
|
||||
if (!writeAllowed || !*writeAllowed) {
|
||||
return this;
|
||||
@ -92,7 +92,7 @@ namespace spades {
|
||||
if (!writeAllowed || !*writeAllowed) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
handle = v;
|
||||
AddRef();
|
||||
return this;
|
||||
@ -101,7 +101,7 @@ namespace spades {
|
||||
if (!writeAllowed || !*writeAllowed) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
handle = v;
|
||||
AddRef();
|
||||
return this;
|
||||
@ -128,12 +128,12 @@ namespace spades {
|
||||
return (std::string)handle;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static CScriptArray *GetAllConfigNames() {
|
||||
auto *ctx = asGetActiveContext();
|
||||
auto *engine = ctx->GetEngine();
|
||||
auto *arrayType = engine->GetTypeInfoByDecl("array<string>");
|
||||
auto *array = CScriptArray::Create(arrayType);
|
||||
auto *array = CScriptArray::Create(arrayType);
|
||||
auto names = Settings::GetInstance()->GetAllItemNames();
|
||||
array->Resize(static_cast<asUINT>(names.size()));
|
||||
for(std::size_t i = 0; i < names.size(); i++) {
|
||||
@ -141,7 +141,7 @@ namespace spades {
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
virtual void Register(ScriptManager *manager, Phase phase) {
|
||||
asIScriptEngine *eng = manager->GetEngine();
|
||||
int r;
|
||||
@ -222,7 +222,7 @@ namespace spades {
|
||||
asMETHOD(ConfigItem, GetStringValue),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterGlobalFunction("array<string>@ GetAllConfigNames()",
|
||||
asFUNCTION(GetAllConfigNames),
|
||||
asCALL_CDECL);
|
||||
@ -233,8 +233,8 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static ConfigRegistrar registrar;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades 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 OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "ScriptManager.h"
|
||||
@ -46,45 +46,45 @@ namespace spades {
|
||||
ArrayType *obj = new ArrayType(initialSize);
|
||||
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
|
||||
return obj;
|
||||
}
|
||||
static ArrayType *Factory3(asUINT initialSize, T initialValue) {
|
||||
if(initialSize > 1024 * 1024 * 256) {
|
||||
asGetActiveContext()->SetException("Too many array elements");
|
||||
return NULL;
|
||||
}
|
||||
ArrayType *obj = new ArrayType(initialSize, initialValue);
|
||||
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
|
||||
return obj;
|
||||
}
|
||||
static ArrayType *Factory4(void *initList) {
|
||||
asUINT length = *reinterpret_cast<const asUINT *>(initList);
|
||||
if(length > 1024 * 1024 * 256) {
|
||||
asGetActiveContext()->SetException("Too many array elements");
|
||||
}
|
||||
ArrayType *obj = new ArrayType(initList);
|
||||
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
static ArrayType *Factory3(asUINT initialSize, T initialValue) {
|
||||
if(initialSize > 1024 * 1024 * 256) {
|
||||
asGetActiveContext()->SetException("Too many array elements");
|
||||
return NULL;
|
||||
}
|
||||
ArrayType *obj = new ArrayType(initialSize, initialValue);
|
||||
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
|
||||
return obj;
|
||||
}
|
||||
static ArrayType *Factory4(void *initList) {
|
||||
asUINT length = *reinterpret_cast<const asUINT *>(initList);
|
||||
if(length > 1024 * 1024 * 256) {
|
||||
asGetActiveContext()->SetException("Too many array elements");
|
||||
}
|
||||
ArrayType *obj = new ArrayType(initList);
|
||||
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
|
||||
return obj;
|
||||
}
|
||||
|
||||
PrimitiveArray(asUINT initialSize = 0) {
|
||||
inner.resize(initialSize);
|
||||
}
|
||||
PrimitiveArray(asUINT initialSize, T initialValue) {
|
||||
inner.resize(initialSize, initialValue);
|
||||
}
|
||||
PrimitiveArray(void *initList) {
|
||||
asUINT length = *reinterpret_cast<const asUINT *>(initList);
|
||||
inner.resize(length);
|
||||
memcpy(inner.data(), reinterpret_cast<const asUINT *>(initList) + 1, inner.size() * sizeof(T));
|
||||
}
|
||||
|
||||
}
|
||||
PrimitiveArray(asUINT initialSize, T initialValue) {
|
||||
inner.resize(initialSize, initialValue);
|
||||
}
|
||||
PrimitiveArray(void *initList) {
|
||||
asUINT length = *reinterpret_cast<const asUINT *>(initList);
|
||||
inner.resize(length);
|
||||
memcpy(inner.data(), reinterpret_cast<const asUINT *>(initList) + 1, inner.size() * sizeof(T));
|
||||
}
|
||||
|
||||
void AddRef() {
|
||||
refCount &= 0x7fffffff;
|
||||
asAtomicInc(refCount);
|
||||
}
|
||||
void Release() {
|
||||
refCount &= 0x7fffffff;
|
||||
|
||||
|
||||
if(asAtomicDec(refCount) <= 0)
|
||||
delete this;
|
||||
}
|
||||
@ -99,7 +99,7 @@ namespace spades {
|
||||
}
|
||||
void EnumReferences(asIScriptEngine *eng) {}
|
||||
void ReleaseAllReferences(asIScriptEngine *eng){}
|
||||
|
||||
|
||||
T& At(asUINT index) {
|
||||
if(index >= inner.size()){
|
||||
asGetActiveContext()->SetException("Index out of bounds");
|
||||
@ -160,7 +160,7 @@ namespace spades {
|
||||
inner.reserve((size_t)siz);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SortAsc(asUINT index, asUINT count){
|
||||
if(count <= 0) return;
|
||||
if(index + count > inner.size()){
|
||||
@ -186,24 +186,24 @@ namespace spades {
|
||||
void SortDesc() {
|
||||
SortDesc(0, GetSize());
|
||||
}
|
||||
|
||||
|
||||
void Reverse() {
|
||||
std::reverse(inner.begin(), inner.end());
|
||||
}
|
||||
|
||||
|
||||
int Find(const T& val) const {
|
||||
typename std::vector<T>::const_iterator it = std::find(inner.begin(), inner.end(), val);
|
||||
if(it == inner.end()) return -1;
|
||||
return static_cast<int> (it - inner.begin());
|
||||
}
|
||||
|
||||
|
||||
int Find(asUINT ind, const T& val) const {
|
||||
if(ind >= GetSize()) return -1;
|
||||
typename std::vector<T>::const_iterator it = std::find(inner.begin() + ind, inner.end(), val);
|
||||
if(it == inner.end()) return -1;
|
||||
return static_cast<int> (it - inner.begin());
|
||||
}
|
||||
|
||||
|
||||
bool operator ==(const ArrayType& array) const {
|
||||
if(this == &array)
|
||||
return true;
|
||||
@ -215,13 +215,13 @@ namespace spades {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool IsEmpty() const {
|
||||
return inner.empty();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class PrimitiveArrayRegistrar: public ScriptObjectRegistrar {
|
||||
std::string typeName;
|
||||
@ -304,154 +304,154 @@ namespace spades {
|
||||
F("void f(int& in)"),
|
||||
asMETHOD(ArrayType, ReleaseAllReferences), asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("%s& opIndex(uint)"),
|
||||
asMETHODPR(ArrayType, At, (asUINT), T&),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("const %s& opIndex(uint) const"),
|
||||
asMETHODPR(ArrayType, At, (asUINT) const, const T&),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("array<%s> &opAssign(const array<%s>&)"),
|
||||
asMETHODPR(ArrayType, operator =, (const ArrayType&), ArrayType&),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void insertAt(uint, const %s& in)"),
|
||||
asMETHODPR(ArrayType, InsertAt, (asUINT, const T&), void),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void removeAt(uint)"),
|
||||
asMETHOD(ArrayType, RemoveAt),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void insertLast(const %s& in)"),
|
||||
asMETHOD(ArrayType, InsertLast),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void removeLast()"),
|
||||
asMETHOD(ArrayType, RemoveLast),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("uint length()"),
|
||||
asMETHOD(ArrayType, GetSize),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void resize(uint)"),
|
||||
asMETHOD(ArrayType, Resize),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void reserve(uint)"),
|
||||
asMETHOD(ArrayType, Reserve),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void sortAsc()"),
|
||||
asMETHODPR(ArrayType, SortAsc, (), void),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void sortAsc(uint, uint)"),
|
||||
asMETHODPR(ArrayType, SortAsc, (asUINT, asUINT), void),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void sortDesc()"),
|
||||
asMETHODPR(ArrayType, SortDesc, (), void),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void sortDesc(uint, uint)"),
|
||||
asMETHODPR(ArrayType, SortDesc, (asUINT, asUINT), void),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("int find(const %s& in) const"),
|
||||
asMETHODPR(ArrayType, Find, (const T&) const, int),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("int find(uint, const %s& in) const"),
|
||||
asMETHODPR(ArrayType, Find, (asUINT, const T&) const, int),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("bool opEquals(const array<%s>&) const"),
|
||||
asMETHODPR(ArrayType, operator ==, (const ArrayType&) const, bool),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("uint get_length()"),
|
||||
asMETHOD(ArrayType, GetSize),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void set_length(uint)"),
|
||||
asMETHOD(ArrayType, Resize),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("bool isEmpty()"),
|
||||
asMETHOD(ArrayType, IsEmpty),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
// STL name
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("uint size()"),
|
||||
asMETHOD(ArrayType, GetSize),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("bool empty()"),
|
||||
asMETHOD(ArrayType, IsEmpty),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void push_back(const %s& in)"),
|
||||
asMETHOD(ArrayType, InsertLast),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void pop_back()"),
|
||||
asMETHOD(ArrayType, RemoveLast),
|
||||
asCALL_THISCALL);
|
||||
manager->CheckError(r);
|
||||
|
||||
|
||||
r = eng->RegisterObjectMethod(ATN(),
|
||||
F("void erase(uint)"),
|
||||
asMETHOD(ArrayType, RemoveAt),
|
||||
@ -474,5 +474,5 @@ namespace spades {
|
||||
static PrimitiveArrayRegistrar<uint64_t> uint64ArrayRegistrar("uint64");
|
||||
static PrimitiveArrayRegistrar<float> floatArrayRegistrar("float");
|
||||
static PrimitiveArrayRegistrar<double> doubleArrayRegistrar("double");
|
||||
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user