diff --git a/graph.cpp b/graph.cpp index 6ff2927f..77e76211 100644 --- a/graph.cpp +++ b/graph.cpp @@ -5042,11 +5042,11 @@ EX ld wall_radar(cell *c, transmatrix T, transmatrix LPe, ld max) { ld step = max / 20; ld fixed_yshift = 0; for(int i=0; i<20; i++) { - T = parallel_transport(T, ori, ztangent(-step)); + T = shift_object(T, ori, ztangent(-step), shift_method(false)); virtualRebase(c, T); color_t col; if(isWall3(c, col) || (WDIM == 2 && GDIM == 3 && tC0(T)[2] > cgi.FLOOR)) { - T = parallel_transport(T, ori, ztangent(step)); + T = shift_object(T, ori, ztangent(step), shift_method(false)); step /= 2; i = 17; if(step < 1e-3) break; } @@ -5126,7 +5126,7 @@ EX void precise_mouseover() { ld step = 0.2; cell *c = centerover; for(int i=0; i<100; i++) { - apply_parallel_transport(T, ori, ztangent(step)); + apply_shift_object(T, ori, ztangent(step)); int pd = through_wall(c, T * C0); if(pd != -1) { color_t col; diff --git a/hyperpoint.cpp b/hyperpoint.cpp index 88efd92d..89b8f787 100644 --- a/hyperpoint.cpp +++ b/hyperpoint.cpp @@ -1646,17 +1646,27 @@ EX eShiftMethod shift_method(bool automatic IS(false)) { return smGeodesic; } -EX transmatrix parallel_transport(const transmatrix Position, const transmatrix& ori, const hyperpoint direction) { - if(nonisotropic) return nisot::parallel_transport(Position, direction); - else if(gproduct) { - hyperpoint h = product::direct_exp(ori * direction); - return Position * rgpushxto0(h); +EX transmatrix shift_object(const transmatrix Position, const transmatrix& ori, const hyperpoint direction, eShiftMethod sm IS(shift_method(true))) { + switch(sm) { + case smGeodesic: + return nisot::parallel_transport(Position, direction); + case smLie: + return nisot::lie_transport(Position, direction); + case smProduct: { + hyperpoint h = product::direct_exp(ori * direction); + return Position * rgpushxto0(h); + } + case smIsometric: { + return Position * rgpushxto0(direct_exp(direction)); + } + case smEmbedded: { + throw hr_exception("not implemented"); + } } - else return Position * rgpushxto0(direct_exp(direction)); } -EX void apply_parallel_transport(transmatrix& Position, const transmatrix orientation, const hyperpoint direction) { - Position = parallel_transport(Position, orientation, direction); +EX void apply_shift_object(transmatrix& Position, const transmatrix orientation, const hyperpoint direction, eShiftMethod sm IS(shift_method(true))) { + Position = shift_object(Position, orientation, direction, sm); } EX void rotate_object(transmatrix& Position, transmatrix& orientation, transmatrix R) { diff --git a/nonisotropic.cpp b/nonisotropic.cpp index d99b7cee..6eaf57a2 100644 --- a/nonisotropic.cpp +++ b/nonisotropic.cpp @@ -2846,10 +2846,16 @@ EX namespace nisot { EX transmatrix parallel_transport(const transmatrix Position, const hyperpoint direction) { auto P = Position; nisot::fixmatrix(P); - if(!geodesic_movement) return eupush(Position * translate(-direction) * inverse(Position) * C0, -1) * Position; return parallel_transport_bare(P, direction); } - + + EX transmatrix lie_transport(const transmatrix Position, const hyperpoint direction) { + transmatrix pshift = eupush( tC0(Position) ); + transmatrix irot = iso_inverse(pshift) * Position; + hyperpoint tH = lie_exp(irot * direction); + return pshift * eupush(tH) * irot; + } + EX transmatrix spin_towards(const transmatrix Position, const hyperpoint goal, flagtype prec IS(pNORMAL)) { hyperpoint at = tC0(Position); diff --git a/shmup.cpp b/shmup.cpp index f3eda845..b8279947 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -1059,7 +1059,7 @@ void movePlayer(monster *m, int delta) { playergoturn[cpid] = 0; if(igo) { go = false; break; } ld r = hypot_d(WDIM, avg_inertia); - apply_parallel_transport(nat.T, m->ori, lrspintox(avg_inertia) * xtangent(r * delta)); + apply_shift_object(nat.T, m->ori, lrspintox(avg_inertia) * xtangent(r * delta)); if(WDIM == 3) rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid])); m->vel = r * (600/SCALE); } @@ -1070,7 +1070,7 @@ void movePlayer(monster *m, int delta) { playersmallspin[cpid] = cspin(0, 1, fspin) * cspin(2, 0, igospan[igo]); if(fspin < 360) igo--; else fspin = 0; } - nat.T = parallel_transport(nat1.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid])); + nat.T = shift_object(nat1.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid])); rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid])); m->inertia[0] = playerstrafe[cpid] / delta; m->inertia[1] = 0; @@ -1078,7 +1078,7 @@ void movePlayer(monster *m, int delta) { } else if(playergo[cpid]) { playergoturn[cpid] = igospan[igo]+godir[cpid]; - nat.T = parallel_transport(nat1.T, m->ori, spin(playergoturn[cpid]) * xtangent(playergo[cpid])); + nat.T = shift_object(nat1.T, m->ori, spin(playergoturn[cpid]) * xtangent(playergo[cpid])); m->inertia = spin(playergoturn[cpid]) * xtangent(playergo[cpid] / delta); } @@ -1168,7 +1168,7 @@ void movePlayer(monster *m, int delta) { int i0 = i; for(int a=0; a<3; a++) v[a] = (i0 % 3) - 1, i0 /= 3; v = v * .1 / hypot_d(3, v); - shiftmatrix T1 = (i == 13) ? nat : shiftless(parallel_transport(nat.T, m->ori, v), nat.shift); + shiftmatrix T1 = (i == 13) ? nat : shiftless(shift_object(nat.T, m->ori, v), nat.shift); cell *c3 = c2; while(true) { cell *c4 = findbaseAround(tC0(T1), c3, 1); @@ -1478,7 +1478,7 @@ void moveMimic(monster *m) { // no need to care about Mirror images, as they already have their 'at' matrix reversed :| if(WDIM == 3) { - nat.T = parallel_transport(nat.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid])); + nat.T = shift_object(nat.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid])); rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid])); } else @@ -1711,10 +1711,10 @@ void moveBullet(monster *m, int delta) { m->dead = true; if(inertia_based) { - nat.T = parallel_transport(nat.T, m->ori, m->inertia * delta); + nat.T = shift_object(nat.T, m->ori, m->inertia * delta); } else - nat.T = parallel_transport(nat.T, m->ori, fronttangent(delta * SCALE * m->vel / speedfactor())); + nat.T = shift_object(nat.T, m->ori, fronttangent(delta * SCALE * m->vel / speedfactor())); cell *c2 = m->findbase(nat, fake::split() ? 10 : 1); if(m->parent && isPlayer(m->parent) && markOrb(itOrbLava) && c2 != m->base && !isPlayerOn(m->base)) @@ -2217,14 +2217,14 @@ void moveMonster(monster *m, int delta) { if(inertia_based) { if(igo) return; - nat.T = parallel_transport(nat.T, m->ori, m->inertia * delta); + nat.T = shift_object(nat.T, m->ori, m->inertia * delta); } else if(WDIM == 3 && igo) { ld fspin = rand() % 1000; - nat.T = parallel_transport(nat0.T, m->ori, cspin(1,2,fspin) * spin(igospan[igo]) * xtangent(step)); + nat.T = shift_object(nat0.T, m->ori, cspin(1,2,fspin) * spin(igospan[igo]) * xtangent(step)); } else { - nat.T = parallel_transport(nat0.T, m->ori, spin(igospan[igo]) * xtangent(step)); + nat.T = shift_object(nat0.T, m->ori, spin(igospan[igo]) * xtangent(step)); } if(m->type != moRagingBull && !peace::on)