Skip to content

Commit b1d3ec7

Browse files
authored
Colision v2 (#915)
* rework bounding boxes * iterating on move-algo * move algo in progress * progress * align "water" camera * start to cleanup legacy move code * cleanups * use persistent water tracking more often * refactor state flags for move * cleanup water walk code * move cleanups * perf * refactor move states * use actual col-box * fix lurker-2-water interaction * npc collision wip * more cleanups * rework ground offset for land-ray * fix incorrect elevation on some animations * npc-npc collision in progress * optimize physics rays * rework angles * npc-to-npc collision * npc: drawing weapons near water * cleanups * cleanup * better "in fly" collisions * fixup * cleanup
1 parent 1f3caac commit b1d3ec7

32 files changed

Lines changed: 791 additions & 778 deletions

game/camera.cpp

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void Camera::save(Serialize &s) {
109109

110110
void Camera::load(Serialize &s, Npc* pl) {
111111
reset(pl);
112-
if(s.version()<54)
112+
if(s.version()<55)
113113
return;
114114
s.read(state.range, state.spin, state.target);
115115
s.read(inter.target, inter.rotOffset);
@@ -375,15 +375,15 @@ Matrix4x4 Camera::mkViewShadowVsm(const Vec3& cameraPos, const Vec3& ldir) const
375375

376376
Matrix4x4 Camera::viewShadow(const Vec3& lightDir, size_t layer) const {
377377
auto vp = viewProj();
378-
float rotation = (180+angles.y);
378+
float rotation = (angles.y-90);
379379
// if(layer==0)
380380
// return viewShadowVsm(cameraPos,rotation,vp,lightDir);
381381
return mkViewShadow(inter.target,rotation,vp,lightDir,layer);
382382
}
383383

384384
Matrix4x4 Camera::viewShadowLwc(const Tempest::Vec3& lightDir, size_t layer) const {
385385
auto vp = viewProjLwc();
386-
float rotation = (180+angles.y);
386+
float rotation = (angles.y-90);
387387
// if(layer==0)
388388
// return viewShadowVsm(cameraPos-origin,rotation,vp,lightDir);
389389
return mkViewShadow(inter.target-origin,rotation,vp,lightDir,layer);
@@ -566,26 +566,26 @@ void Camera::implMove(Tempest::Event::KeyType key, uint64_t dt) {
566566
float dpos = float(dt);
567567
float dRot = dpos/15.f;
568568
float k = float(M_PI/180.0);
569-
float s = std::sin(angles.y*k), c=std::cos(angles.y*k);
569+
float s = std::sin(-angles.y*k), c=std::cos(-angles.y*k);
570570
float sx = std::sin(angles.x*k);
571571
float cx = std::cos(angles.x*k);
572572

573573
if(key==KeyEvent::K_A) {
574-
origin.x += dpos*c;
575-
origin.z += dpos*s;
574+
origin.x += dpos*s;
575+
origin.z += dpos*c;
576576
}
577577
if(key==KeyEvent::K_D) {
578-
origin.x -= dpos*c;
579-
origin.z -= dpos*s;
578+
origin.x -= dpos*s;
579+
origin.z -= dpos*c;
580580
}
581581
if(key==KeyEvent::K_W) {
582-
origin.x += dpos*s*cx;
583-
origin.z -= dpos*c*cx;
582+
origin.x += dpos*c*cx;
583+
origin.z -= dpos*s*cx;
584584
origin.y -= dpos*sx;
585585
}
586586
if(key==KeyEvent::K_S) {
587-
origin.x -= dpos*s*cx;
588-
origin.z += dpos*c*cx;
587+
origin.x -= dpos*c*cx;
588+
origin.z += dpos*s*cx;
589589
origin.y += dpos*sx;
590590
}
591591
if(key==KeyEvent::K_Q)
@@ -753,9 +753,14 @@ void Camera::tick(uint64_t dt) {
753753
auto pl = isFree() ? nullptr : world->player();
754754
auto& physic = *world->physic();
755755

756-
if(pl!=nullptr && !pl->isInWater()) {
756+
if(pl!=nullptr && pl->isSwim()) {
757+
inWater = (angles.x < -8.f);
758+
}
759+
else if(pl!=nullptr && (pl->isInAir() || pl->isJump()) && !pl->isDead()) {
760+
// NOTE: not quite correct
757761
inWater = physic.cameraRay(inter.target, origin).waterCol % 2;
758-
} else {
762+
}
763+
else {
759764
// NOTE: find a way to avoid persistent tracking
760765
inWater = inWater ^ (physic.cameraRay(prev, origin).waterCol % 2);
761766
}
@@ -778,12 +783,10 @@ void Camera::tickFirstPerson(float /*dtF*/) {
778783
void Camera::tickThirdPerson(float dtF) {
779784
const auto& def = cameraDef();
780785

781-
auto mkRotMatrix = [](Vec3 spin){
782-
auto rotOffsetMat = Matrix4x4::mkIdentity();
783-
rotOffsetMat.rotateOY(180-spin.y);
784-
rotOffsetMat.rotateOX(spin.x);
785-
rotOffsetMat.rotateOZ(spin.z);
786-
return rotOffsetMat;
786+
auto mkRotMatrix = [this](Vec3 spin){
787+
auto view = Camera::mkRotation(spin);
788+
view.inverse();
789+
return view;
787790
};
788791

789792
auto targetOffset = Vec3(def.target_offset_x,
@@ -817,7 +820,7 @@ void Camera::tickThirdPerson(float dtF) {
817820
inter.target = followTarget(inter.target, state.target+targetOffset, dtF);
818821
}
819822

820-
auto dir = Vec3{0,0,-1};
823+
auto dir = Vec3{0,0,1};
821824
rotOffsetMat.project(dir);
822825

823826
if(true && def.collision!=0) {
@@ -830,7 +833,7 @@ void Camera::tickThirdPerson(float dtF) {
830833
rotation.x = 80;
831834
rotation.y = state.spin.y;
832835
const auto rotOffsetMat = mkRotMatrix(rotation);
833-
dir = Vec3{0,0,-1};
836+
dir = Vec3{0,0,1};
834837
rotOffsetMat.project(dir);
835838
}
836839
}
@@ -893,16 +896,16 @@ float Camera::calcCameraColision(const Tempest::Vec3& target, const Tempest::Vec
893896
}
894897

895898
Vec3 Camera::calcLookAtAngles(const Tempest::Vec3& origin, const Tempest::Vec3& target, const Vec3& rotOffset, const Vec3& defSpin) const {
896-
auto sXZ = (origin - target);
899+
auto sXZ = (target - origin);
897900

898901
float lenXZ = Vec2(sXZ.x,sXZ.z).length();
899-
float y0 = std::atan2(sXZ.x, sXZ.z)*180.f/float(M_PI);
902+
float y0 = std::atan2(sXZ.z, sXZ.x)*180.f/float(M_PI);
900903
float x0 = std::atan2(sXZ.y, lenXZ)*180.f/float(M_PI);
901904

902905
if(lenXZ < 4.f)
903-
y0 = -defSpin.y;
906+
y0 = defSpin.y;
904907

905-
return Vec3(x0,-y0,0) - rotOffset;
908+
return Vec3(-x0,y0,0) - rotOffset;
906909
}
907910

908911
Vec3 Camera::calcCameraColision(const Tempest::Vec3& from, const Tempest::Vec3& dir) const {
@@ -943,23 +946,21 @@ Vec3 Camera::clampRotation(Tempest::Vec3 spin) {
943946
}
944947

945948
Matrix4x4 Camera::mkView(const Vec3& pos, const Vec3& spin) const {
946-
Matrix4x4 view;
947-
view.identity();
949+
auto view = Matrix4x4::mkIdentity();
948950
view.scale(-1,-1,-1);
949951

950-
// view.translate(0,0,-zNear());
951952
view.mul(mkRotation(spin));
952953
view.translate(-pos);
953954

954955
return view;
955956
}
956957

957958
Matrix4x4 Camera::mkRotation(const Vec3& spin) const {
958-
Matrix4x4 view;
959-
view.identity();
959+
auto view = Matrix4x4::mkIdentity();
960960
view.rotateOX(spin.x);
961961
view.rotateOY(spin.y);
962962
view.rotateOZ(spin.z);
963+
view.rotateOY(90); // X forward
963964
return view;
964965
}
965966

@@ -972,7 +973,7 @@ void Camera::debugDraw(DbgPainter& p) {
972973
p.drawLine(inter.target, origin);
973974

974975
if(auto pl = Gothic::inst().player()) {
975-
float a = pl->rotationRad();
976+
float a = pl->rotationRad()+float(M_PI*0.5);
976977
float c = std::cos(a), s = std::sin(a);
977978
auto ln = Vec3(c,0,s)*25.f;
978979
p.drawLine(inter.target-ln, inter.target+ln);
@@ -993,7 +994,7 @@ void Camera::debugDraw(DbgPainter& p) {
993994
buf = string_frm("Range To Player : ", (inter.target-origin).length());
994995
p.drawText(8,y,buf); y += fnt.pixelSize();
995996

996-
buf = string_frm("Azimuth : ", angleMod(state.spin.y-angles.y));
997+
buf = string_frm("Azimuth : ", angleMod(angles.y-state.spin.y));
997998
p.drawText(8,y,buf); y += fnt.pixelSize();
998999
buf = string_frm("Elevation : ", inter.rotOffset.x+angles.x);
9991000
p.drawText(8,y,buf); y += fnt.pixelSize();

game/game/fightalgo.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,22 @@ bool FightAlgo::isInGRange(const Npc &npc, const Npc &tg, GameScript &owner) con
301301
bool FightAlgo::isInFocusAngle(const Npc &npc, const Npc &tg) const {
302302
static const float maxAngle = std::cos(float(30.0*M_PI/180.0));
303303

304-
const auto dpos = npc.centerPosition()-tg.centerPosition();
305-
const float plAng = npc.rotationRad()+float(M_PI/2);
304+
const auto dpos = tg.centerPosition() - npc.centerPosition();
305+
const float plAng = npc.rotationRad();
306+
307+
const float da = plAng-std::atan2(dpos.z,dpos.x);
308+
const float c = std::cos(da);
309+
310+
if(c<maxAngle)
311+
return false;
312+
return true;
313+
}
314+
315+
bool FightAlgo::isInJumpBackAngle(const Npc& npc, const Npc& tg) const {
316+
static const float maxAngle = std::cos(float(90.0*M_PI/180.0));
317+
318+
const auto dpos = tg.centerPosition() - npc.centerPosition();
319+
const float plAng = npc.rotationRad();
306320

307321
const float da = plAng-std::atan2(dpos.z,dpos.x);
308322
const float c = std::cos(da);

game/game/fightalgo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class FightAlgo final {
5454
bool isInWRange (const Npc &npc, const Npc &tg, GameScript &owner) const;
5555
bool isInGRange (const Npc &npc, const Npc &tg, GameScript &owner) const;
5656
bool isInFocusAngle (const Npc &npc, const Npc &tg) const;
57+
bool isInJumpBackAngle (const Npc &npc, const Npc &tg) const;
5758

5859
private:
5960
void fillQueue(Npc &npc, Npc &tg, GameScript& owner);

game/game/gamescript.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,7 @@ void GameScript::wld_spawnnpcrange(std::shared_ptr<zenkit::INpc> npcRef, int cls
18501850
(void)lifeTime;
18511851
for(int32_t i=0;i<count;++i) {
18521852
auto* npc = world().addNpc(size_t(clsId),at->position());
1853-
fixNpcPosition(*npc,at->rotation()-90 + 360.f*float(i)/float(count),100);
1853+
fixNpcPosition(*npc,at->rotation() + 360.f*float(i)/float(count),100);
18541854
}
18551855
}
18561856

game/game/gamesession.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ GameSession::GameSession(std::string file) {
9090
//std::string_view hero = "PC_HERO";
9191
//std::string_view hero = "FireGolem";
9292
//std::string_view hero = "Dragon_Undead";
93+
//std::string_view hero = "Wolf";
9394
//std::string_view hero = "Sheep";
9495
//std::string_view hero = "Giant_Bug";
9596
//std::string_view hero = "OrcWarrior_Rest";
@@ -101,6 +102,7 @@ GameSession::GameSession(std::string file) {
101102
//std::string_view hero = "FireWaran";
102103
//std::string_view hero = "Bloodfly";
103104
//std::string_view hero = "Gobbo_Skeleton";
105+
//std::string_view hero = "Swampshark";
104106
if(!Gothic::inst().isBenchmarkMode())
105107
wrld->createPlayer(hero);
106108
wrld->postInit();

0 commit comments

Comments
 (0)