openspades/Sources/Client/Client_Scene.cpp

749 lines
24 KiB
C++
Raw Normal View History

2014-03-09 21:43:38 +09:00
/*
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"
#include <cstdlib>
#include <Core/ConcurrentDispatch.h>
#include <Core/Settings.h>
#include <Core/Strings.h>
#include "World.h"
#include "Weapon.h"
#include "GameMap.h"
#include "Player.h"
#include "Corpse.h"
#include "Grenade.h"
#include "IGameMode.h"
#include "TCGameMode.h"
#include "CTFGameMode.h"
#include "ClientPlayer.h"
#include "ILocalEntity.h"
#include "NetClient.h"
SPADES_SETTING(cg_fov, "68");
SPADES_SETTING(cg_thirdperson, "0");
SPADES_SETTING(cg_manualFocus, "0");
2014-03-09 21:43:38 +09:00
static float nextRandom() {
return (float)rand() / (float)RAND_MAX;
}
namespace spades {
namespace client {
#pragma mark - Drawing
bool Client::ShouldRenderInThirdPersonView() {
if(world && world->GetLocalPlayer()){
if(!world->GetLocalPlayer()->IsAlive())
return true;
}
if ((int)cg_thirdperson != 0 && world->GetNumPlayers() <= 1) {
return true;
}
2014-03-09 21:43:38 +09:00
return false;
}
float Client::GetLocalFireVibration() {
float localFireVibration = 0.f;
localFireVibration = time - localFireVibrationTime;
localFireVibration = 1.f - localFireVibration / 0.1f;
if(localFireVibration < 0.f)
localFireVibration = 0.f;
return localFireVibration;
}
float Client::GetAimDownZoomScale(){
if(world == nullptr ||
world->GetLocalPlayer() == nullptr ||
world->GetLocalPlayer()->IsToolWeapon() == false ||
world->GetLocalPlayer()->IsAlive() == false)
return 1.f;
float delta = .8f;
switch(world->GetLocalPlayer()->GetWeapon()->GetWeaponType()) {
case SMG_WEAPON:
delta = .8f;
break;
case RIFLE_WEAPON:
delta = 1.4f;
break;
case SHOTGUN_WEAPON:
delta = .4f;
break;
}
float aimDownState = GetAimDownState();
return 1.f + powf(aimDownState, 5.f) * delta;
}
SceneDefinition Client::CreateSceneDefinition() {
SPADES_MARK_FUNCTION();
SceneDefinition def;
def.time = (unsigned int)(time * 1000.f);
def.denyCameraBlur = true;
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();
2014-04-08 01:46:08 +09:00
def.blurVignette = .0f;
2014-03-09 21:43:38 +09:00
if(IsFollowing()){
int limit = 100;
// if current following player has left,
// or removed,
// choose next player.
while(!world->GetPlayer(followingPlayerId) ||
world->GetPlayer(followingPlayerId)->GetFront().GetPoweredLength() < .01f){
FollowNextPlayer(false);
if((limit--) <= 0){
break;
}
}
player = world->GetPlayer(followingPlayerId);
}
if(player){
float roll = 0.f;
float scale = 1.f;
float vibPitch = 0.f;
float vibYaw = 0.f;
if(ShouldRenderInThirdPersonView() ||
(IsFollowing() && player != world->GetLocalPlayer())){
Vector3 center = player->GetEye();
Vector3 playerFront = player->GetFront2D();
Vector3 up = MakeVector3(0,0,-1);
if((!player->IsAlive()) && lastMyCorpse &&
player == world->GetLocalPlayer()){
center = lastMyCorpse->GetCenter();
}
if(map->IsSolidWrapped((int)floorf(center.x),
(int)floorf(center.y),
(int)floorf(center.z))){
float z = center.z;
while(z > center.z - 5.f){
if(!map->IsSolidWrapped((int)floorf(center.x),
(int)floorf(center.y),
(int)floorf(z))){
center.z = z;
break;
}else{
z -= 1.f;
}
}
}
float distance = 5.f;
if(player == world->GetLocalPlayer() &&
world->GetLocalPlayer()->GetTeamId() < 2 &&
!world->GetLocalPlayer()->IsAlive()){
// deathcam.
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;
eye += playerFront * 3.f;
eye += up * -.1f;
eye += player->GetRight() *2.f;
scale *= .6f;
}
// try ray casting
GameMap::RayCastResult result;
result = map->CastRay2(center, (eye - center).Normalize(), 256);
if(result.hit) {
float dist = (result.hitPos - center).GetLength();
float curDist = (eye - center).GetLength();
dist -= 0.3f; // near clip plane
if(curDist > dist){
float diff = curDist - dist;
eye += (center - eye).Normalize() * diff;
}
}
Vector3 front = center - eye;
front = front.Normalize();
2014-12-17 01:17:03 +10:00
if(FirstPersonSpectate == false){
def.viewOrigin = eye;
def.viewAxis[0] = -Vector3::Cross(up, front).Normalize();
def.viewAxis[1] = -Vector3::Cross(front, def.viewAxis[0]).Normalize();
def.viewAxis[2] = front;
}else{
def.viewOrigin = player->GetEye();
def.viewAxis[0] = player->GetRight();
def.viewAxis[1] = player->GetUp();
def.viewAxis[2] = player->GetFront();
}
2014-03-09 21:43:38 +09:00
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();
float localFireVibration = GetLocalFireVibration();
localFireVibration *= localFireVibration;
2014-03-11 03:54:01 +09:00
if(player->GetTool() == Player::ToolSpade) {
2014-03-11 03:57:17 +09:00
localFireVibration *= 0.4f;
2014-03-11 03:54:01 +09:00
}
2014-03-09 21:43:38 +09:00
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;
2014-03-11 03:54:01 +09:00
2014-03-11 03:57:17 +09:00
def.radialBlur += localFireVibration * 0.2f;
2014-03-09 21:43:38 +09:00
// 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;
2014-03-09 21:43:38 +09:00
2014-04-08 01:46:08 +09:00
def.blurVignette = .0f;
2014-03-09 21:43:38 +09:00
}
// add vibration for both 1st/3rd view
{
// add grenade vibration
float grenVib = grenadeVibration;
if(grenVib > 0.f){
grenVib *= 10.f;
if(grenVib > 1.f)
grenVib = 1.f;
roll += (nextRandom() - nextRandom()) * 0.2f * grenVib;
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;
}
{
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){
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){
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.zFar = 130.f;
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.zFar = 130.f;
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.zFar = 130.f;
def.skipWorld = true;
renderer->SetFogColor(MakeVector3(0,0,0));
}
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.depthOfFieldFarBlurStrength = 1.f;
def.depthOfFieldFocalLength = focalLength;
}
2014-03-09 21:43:38 +09:00
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];
v[0][0][0] = (mat * MakeVector3(0,0,0)).GetXYZ();
v[0][0][1] = (mat * MakeVector3(0,0,1)).GetXYZ();
v[0][1][0] = (mat * MakeVector3(0,1,0)).GetXYZ();
v[0][1][1] = (mat * MakeVector3(0,1,1)).GetXYZ();
v[1][0][0] = (mat * MakeVector3(1,0,0)).GetXYZ();
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());
int tId;
IModel *base = renderer->RegisterModel("Models/MapObjects/CheckPoint.kv6");
IModel *intel = renderer->RegisterModel("Models/MapObjects/Intel.kv6");
for(tId = 0; tId < 2; tId++){
CTFGameMode::Team& team = mode->GetTeam(tId);
IntVector3 col = world->GetTeam(tId).color;
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);
param.matrix = param.matrix * Matrix4::Scale(.1f);
renderer->RenderModel(intel, param);
}
}
}
void Client::DrawTCObjects() {
SPADES_MARK_FUNCTION();
TCGameMode *mode = static_cast<TCGameMode *>(world->GetMode());
int tId;
IModel *base = renderer->RegisterModel("Models/MapObjects/CheckPoint.kv6");
int cnt = mode->GetNumTerritories();
for(tId = 0; tId < cnt; tId++){
TCGameMode::Territory *t = mode->GetTerritory(tId);
IntVector3 col;
if(t->ownerTeamId == 2){
col = IntVector3::Make(255, 255, 255);
}else{
col = world->GetTeam(t->ownerTeamId).color;
}
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(i)){
SPAssert(clientPlayers[i]);
clientPlayers[i]->AddToScene();
}
std::vector<Grenade *> nades = world->GetAllGrenades();
for(size_t i = 0; i < nades.size(); i++){
AddGrenadeToScene(nades[i]);
}
{
for(auto& c: corpses){
Vector3 center = c->GetCenter();
if((center - lastSceneDef.viewOrigin).GetPoweredLength() > 150.f * 150.f)
continue;
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){
2014-03-11 03:42:04 +09:00
if(p->IsReadyToUseTool() &&
2014-03-14 23:29:52 +09:00
p->GetTool() == Player::ToolBlock &&
p->IsAlive()){
2014-03-09 21:43:38 +09:00
std::vector<IntVector3> blocks;
if(p->IsBlockCursorDragging()){
2014-03-11 03:42:04 +09:00
blocks = std::move
(world->CubeLine(p->GetBlockCursorDragPos(),
p->GetBlockCursorPos(),
256));
2014-03-09 21:43:38 +09:00
}else{
blocks.push_back(p->GetBlockCursorPos());
}
2014-03-11 03:42:04 +09:00
bool active = p->IsBlockCursorActive();
2014-03-09 21:43:38 +09:00
Vector4 color = {1,1,1,1};
2014-03-11 03:42:04 +09:00
if(!active)
color = Vector4(1,1,0,1);
2014-03-09 21:43:38 +09:00
if((int)blocks.size() > p->GetNumBlocks())
color = MakeVector4(1,0,0,1);
2014-03-11 03:42:04 +09:00
if(!active)
color.w *= 0.5f;
2014-03-09 21:43:38 +09:00
for(size_t i = 0; i < blocks.size(); i++){
IntVector3& v = blocks[i];
2014-03-11 03:42:04 +09:00
if(active) {
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+1, v.z),
MakeVector3(v.x+1, v.y+1, v.z),
color);
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z+1),
MakeVector3(v.x+1, v.y, v.z+1),
color);
renderer->AddDebugLine(MakeVector3(v.x, v.y+1, 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+1, v.y, v.z),
color);
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
MakeVector3(v.x, v.y+1, v.z),
color);
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z+1),
MakeVector3(v.x, v.y+1, v.z+1),
color);
renderer->AddDebugLine(MakeVector3(v.x+1, v.y, v.z),
MakeVector3(v.x+1, v.y+1, v.z),
color);
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);
renderer->AddDebugLine(MakeVector3(v.x, v.y+1, v.z),
MakeVector3(v.x, v.y+1, v.z+1),
color);
renderer->AddDebugLine(MakeVector3(v.x+1, v.y, v.z),
MakeVector3(v.x+1, v.y, v.z+1),
color);
renderer->AddDebugLine(MakeVector3(v.x+1, v.y+1, v.z),
MakeVector3(v.x+1, v.y+1, v.z+1),
color);
}else{
// not active
const float ln = 0.1f;
{
float xx = v.x, yy = v.y, zz = v.z;
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx+ln, yy, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy+ln, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz+ln), color);
}
{
float xx = v.x + 1, yy = v.y, zz = v.z;
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx-ln, yy, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy+ln, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz+ln), color);
}
{
float xx = v.x, yy = v.y + 1, zz = v.z;
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx+ln, yy, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy-ln, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz+ln), color);
}
{
float xx = v.x + 1, yy = v.y + 1, zz = v.z;
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx-ln, yy, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy-ln, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz+ln), color);
}
{
float xx = v.x, yy = v.y, zz = v.z + 1;
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx+ln, yy, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy+ln, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz-ln), color);
}
{
float xx = v.x + 1, yy = v.y, zz = v.z + 1;
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx-ln, yy, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy+ln, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz-ln), color);
}
{
float xx = v.x, yy = v.y + 1, zz = v.z + 1;
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx+ln, yy, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy-ln, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz-ln), color);
}
{
float xx = v.x + 1, yy = v.y + 1, zz = v.z + 1;
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx-ln, yy, zz), color);
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
2014-03-09 21:43:38 +09:00
}
}
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
{
hitTag_t tag = hit_None;
Player *hottracked = HotTrackedPlayer( &tag );
if(hottracked){
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 );
AddDebugObjectToScene(hb.limbs[0], (tag & hit_Legs) ? color2 : color );
AddDebugObjectToScene(hb.limbs[1], (tag & hit_Legs) ? color2 : color );
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;
}
}
}